bitkeeper revision 1.289.1.2 (3f0aa5f5RZ04FODq-SZaRpQyRs03AA)
authorrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>
Tue, 8 Jul 2003 11:07:33 +0000 (11:07 +0000)
committerrac61@labyrinth.cl.cam.ac.uk <rac61@labyrinth.cl.cam.ac.uk>
Tue, 8 Jul 2003 11:07:33 +0000 (11:07 +0000)
Refactoring partially complete, code reformatting, cleanups, documentation
Fix disk number handling so that it masks the correct number of bits.

28 files changed:
tools/control/src/org/xenoserver/cmdline/CommandParser.java
tools/control/src/org/xenoserver/cmdline/ParsePartitionsAdd.java
tools/control/src/org/xenoserver/cmdline/ParsePartitionsList.java
tools/control/src/org/xenoserver/cmdline/ParsePhysicalGrant.java
tools/control/src/org/xenoserver/cmdline/ParsePhysicalList.java
tools/control/src/org/xenoserver/cmdline/ParsePhysicalRevoke.java
tools/control/src/org/xenoserver/cmdline/ParseVdCreate.java
tools/control/src/org/xenoserver/cmdline/ParseVdDelete.java
tools/control/src/org/xenoserver/cmdline/ParseVdFree.java
tools/control/src/org/xenoserver/cmdline/ParseVdShow.java
tools/control/src/org/xenoserver/control/CommandPartitionAdd.java
tools/control/src/org/xenoserver/control/CommandPhysicalList.java
tools/control/src/org/xenoserver/control/CommandVdCreate.java
tools/control/src/org/xenoserver/control/CommandVdDelete.java
tools/control/src/org/xenoserver/control/CommandVdRefresh.java
tools/control/src/org/xenoserver/control/Extent.java
tools/control/src/org/xenoserver/control/InetAddressPattern.java
tools/control/src/org/xenoserver/control/Library.java
tools/control/src/org/xenoserver/control/Mode.java
tools/control/src/org/xenoserver/control/Partition.java
tools/control/src/org/xenoserver/control/PartitionManager.java
tools/control/src/org/xenoserver/control/Settings.java
tools/control/src/org/xenoserver/control/StringPattern.java
tools/control/src/org/xenoserver/control/VirtualBlockDevice.java
tools/control/src/org/xenoserver/control/VirtualDisk.java
tools/control/src/org/xenoserver/control/VirtualDiskManager.java
tools/control/src/org/xenoserver/control/XML.java
tools/control/src/org/xenoserver/control/XMLHelper.java

index e04b1cb7d384a66dfe2f9ea667c5c6d8b83efb9b..35b7c236be6ebf0925c49fa48d4b1a3c1dd122e5 100644 (file)
@@ -89,10 +89,10 @@ public abstract class CommandParser {
   }
 
   protected void loadState() {
-    XML.load_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_INPUT_FILE );
+    XML.loadState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_INPUT_FILE );
   }
   
   protected void saveState() {
-    XML.dump_state( PartitionManager.it, VirtualDiskManager.it, Settings.STATE_OUTPUT_FILE );
+    XML.saveState( PartitionManager.IT, VirtualDiskManager.IT, Settings.STATE_OUTPUT_FILE );
   }
 }
index 63f6dce36eb1ecb245932f30e3953fa6f66286c5..67e4902b9b5f79e83cb256f102587316e8e2b81c 100644 (file)
@@ -19,19 +19,19 @@ public class ParsePartitionsAdd extends CommandParser {
     if (partition_name.equals(""))
       throw new ParseFailedException("Expected -p<partition_name>");
       
-    long chunksize = Library.parse_size( size ) / Settings.SECTOR_SIZE;
+    long chunksize = Library.parseSize( size ) / Settings.SECTOR_SIZE;
     if ( chunksize <= 0 )
       throw new CommandFailedException("Chunk size " + size + " is smaller than sector size.");
     
     // Initialise the partition manager and look up the partition
     loadState();
-    Partition p = PartitionManager.it.get_partition(partition_name);
+    Partition p = PartitionManager.IT.getPartition(partition_name);
     
     if ( p == null )
       throw new CommandFailedException("Partition " + partition_name + " does not exist.");
     
     // Check if this partition belongs to the VDM
-    if (p.getIsXeno() && !force)
+    if (p.isXeno() && !force)
       throw new CommandFailedException("Refusing to add partition as it is already allocated to the virtual disk manager. Use -f if you are sure.");
     
     String output = new CommandPartitionAdd( p, chunksize ).execute();
index 78534614639787f20f9eb6ee5a86db31ab8dfb22..ac60c6e591cd02513acf8d721351b3c01b5277a0 100644 (file)
@@ -12,26 +12,26 @@ import org.xenoserver.control.PartitionManager;
 public class ParsePartitionsList extends CommandParser {
   public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
     loadState();
-    Iterator i = PartitionManager.it.iterator();
+    Iterator i = PartitionManager.IT.iterator();
     int idx = 1;
     System.out.println( "     maj:min " + "    blocks " + "start sect " +
                         " num sects " + "name" );
     while (i.hasNext()) {
       Partition p = (Partition) i.next();
 
-      if (p.getIsXeno()) {
+      if (p.isXeno()) {
         System.out.print("[ ");
       } else {
         System.out.print("  ");
       }
-      System.out.print(Library.format(idx++, 2, 0) + " ");
-      System.out.print(Library.format(p.getMajor(),3,0) + ":" + 
-          Library.format(p.getMinor(),3,1) + " " +
-          Library.format(p.getBlocks(),10,0) + " " +
-          Library.format(p.getStartSect(),10,0) + " " +
-          Library.format(p.getNumSects(),10,0) + " " +
-          Library.format(p.getName(),7,1));   
-      if (p.getIsXeno()) {
+      System.out.print(Library.format(idx++, 2, false) + " ");
+      System.out.print(Library.format(p.getMajor(),3,false) + ":" + 
+          Library.format(p.getMinor(),3,true) + " " +
+          Library.format(p.getBlocks(),10,false) + " " +
+          Library.format(p.getStartSect(),10,false) + " " +
+          Library.format(p.getNumSects(),10,false) + " " +
+          Library.format(p.getName(),7,true));   
+      if (p.isXeno()) {
         System.out.println("]");
       } else {
         System.out.println();
index 9979d6e4f0cc1bdf464da624332e4065d39e0026..af3c7a6b4799d55c9f5494950b48fe603f37b828 100644 (file)
@@ -30,13 +30,13 @@ public class ParsePhysicalGrant extends CommandParser {
       
     // Initialise the partition manager and look up the partition
     loadState();
-    Partition p = PartitionManager.it.get_partition(partition_name);
+    Partition p = PartitionManager.IT.getPartition(partition_name);
     
     if ( p == null )
       throw new CommandFailedException("Partition " + partition_name + " does not exist.");
     
     // Check if this partition belongs to the VDM
-    if (p.getIsXeno() && !force)
+    if (p.isXeno() && !force)
       throw new CommandFailedException("Refusing to grant physical access as the given partition is allocated to the virtual disk manager. Use -f if you are sure.");
      
     // Convert the partition into a physical extent
index 84d849a28c994b5c8cfab58b06e0e7a32767dd78..18a4400e80f406aefd1a28a61e20ddc95592f097 100644 (file)
@@ -35,23 +35,23 @@ public class ParsePhysicalList extends CommandParser {
       Entry entry = (Entry) i.next(); 
       Extent e = (Extent) entry.getKey();
       String mode = entry.getValue().toString();
-      Partition p = PartitionManager.it.get_partition( e );
+      Partition p = PartitionManager.IT.getPartition( e );
       if ( p != null ) {
-        System.out.println(Library.format(p.getMajor(),3,0) + ":" + 
-          Library.format(p.getMinor(),3,1) + " " +
-          Library.format(p.getBlocks(),10,0) + " " +
-          Library.format(p.getStartSect(),10,0) + " " +
-          Library.format(p.getNumSects(),10,0) + " " +
-          Library.format(p.getName(),7,1) + " " +
-          Library.format(mode,2,1));   
+        System.out.println(Library.format(p.getMajor(),3,false) + ":" + 
+          Library.format(p.getMinor(),3,true) + " " +
+          Library.format(p.getBlocks(),10,false) + " " +
+          Library.format(p.getStartSect(),10,false) + " " +
+          Library.format(p.getNumSects(),10,false) + " " +
+          Library.format(p.getName(),7,true) + " " +
+          Library.format(mode,2,true));   
       } else {
-        System.out.println(Library.format(e.getMajor(),3,0) + ":" +
-          Library.format(e.getMinor(),3,1) + " " +
+        System.out.println(Library.format(e.getMajor(),3,false) + ":" +
+          Library.format(e.getMinor(),3,true) + " " +
           "          " + " " +
-          Library.format(e.getOffset(),10,0) + " " +
-          Library.format(e.getSize(),10,0) + " " +
+          Library.format(e.getOffset(),10,false) + " " +
+          Library.format(e.getSize(),10,false) + " " +
           "       " + " " +
-          Library.format(mode,2,1));
+          Library.format(mode,2,true));
       }
     }
   }
index 9db83a5b85f963e434bc3972e617632e22f1036a..5c0e80201f270176e1adf9a62738f708fd057dcc 100644 (file)
@@ -21,7 +21,7 @@ public class ParsePhysicalRevoke extends CommandParser {
       
     // Initialise the partition manager and look up the partition
     loadState();
-    Partition p = PartitionManager.it.get_partition(partition_name);
+    Partition p = PartitionManager.IT.getPartition(partition_name);
     
     if ( p == null )
       throw new CommandFailedException("Partition " + partition_name + " does not exist.");
index 9075039a29d551f2dd82404aef876292ad5ff074..4f4210f22fbbadc440fc0745de43fbba81546d38 100644 (file)
@@ -25,7 +25,7 @@ public class ParseVdCreate extends CommandParser {
     else
       expiry = new Date(Date.parse(expiry_s));
       
-    long size = Library.parse_size(size_s);
+    long size = Library.parseSize(size_s);
     
     loadState();
     String output = new CommandVdCreate(name,size/Settings.SECTOR_SIZE,expiry).execute();
index 20713e53663f51b36c5003e4fded2fb8bccbdc12..bcd400876ed883b4c414010d3ad9aafb9cd6231a 100644 (file)
@@ -15,7 +15,7 @@ public class ParseVdDelete extends CommandParser {
       throw new ParseFailedException("Expected -k<key>");
     
     loadState();
-    if ( VirtualDiskManager.it.get_virtual_disk_key(vd_key) == null )
+    if ( VirtualDiskManager.IT.getVirtualDisk(vd_key) == null )
       throw new CommandFailedException("Virtual disk " + vd_key + " does not exist");
       
     String output = new CommandVdDelete(vd_key).execute();
index 7bd3e8a804f3672807fc530e0a6153f990cc9929..ea62f8998f7c29f3b64eb6bd6df0302ec0ff227b 100644 (file)
@@ -16,17 +16,17 @@ public class ParseVdFree extends CommandParser {
     boolean verbose = getFlagParameter(args, 'v');
     
     loadState();
-    VirtualDisk free = VirtualDiskManager.it.getFreeVirtualDisk();
+    VirtualDisk free = VirtualDiskManager.IT.getFreeDisk();
     System.out.println( "Free disk has " + free.getExtentCount() + " extents totalling "
-                      + Library.format_size(free.getSize()*Settings.SECTOR_SIZE,8,1) );
+                      + Library.formatSize(free.getSize()*Settings.SECTOR_SIZE,8,true) );
     if ( verbose ) {
-      Iterator i = free.iterator();
+      Iterator i = free.extents();
       System.out.println("  disk       offset         size");
       while (i.hasNext()) {
         Extent e = (Extent) i.next();
-        System.out.println( Library.format(e.getDisk(), 6, 0) + " "
-                          + Library.format(e.getOffset(), 12, 0) + " "
-                          + Library.format(e.getSize(), 12, 0) );
+        System.out.println( Library.format(e.getDisk(), 6, false) + " "
+                          + Library.format(e.getOffset(), 12, false) + " "
+                          + Library.format(e.getSize(), 12, false) );
       }
     }
   }
index 287a24621af8cbe77e8b030f9e2fe83765446dae..af655739023bd85356dce32a10a3b5d3a2d07b16 100644 (file)
@@ -13,41 +13,42 @@ import org.xenoserver.control.VirtualDiskManager;
 
 public class ParseVdShow extends CommandParser {
   public void parse(Defaults d, LinkedList args) throws ParseFailedException, CommandFailedException {
-    int vd_num = getIntParameter(args,'n',-1);
+    String key = getStringParameter(args,'k',"");
     
     loadState();
     
-    if ( vd_num < 0 ) {
-      System.out.println("num key        expiry                       name                 size");
-      for (int i=0;i<VirtualDiskManager.it.getVirtualDiskCount();i++) {
-        VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(i);
-        System.out.print( Library.format(i,3,0) + " " + vd.getKey() + " " );
+    if ( key.equals("") ) {
+      System.out.println("key        expiry                       name                 size");
+      Iterator i = VirtualDiskManager.IT.getVirtualDisks();
+      while ( i.hasNext() ) {
+        VirtualDisk vd = (VirtualDisk) i.next();
+        System.out.print( vd.getKey() + " " );
         if ( vd.getExpiry() != null )
           System.out.print( vd.getExpiry().toString() );
         else
           System.out.print( "                            " );
-        System.out.println( " " + Library.format(vd.getName(),16,1) + " "
-                          + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,0) );
+        System.out.println( " " + Library.format(vd.getName(),16,true) + " "
+                          + Library.formatSize(vd.getSize()*Settings.SECTOR_SIZE,8,false) );
       }
     } else {
-      VirtualDisk vd = VirtualDiskManager.it.getVirtualDisk(vd_num);
+      VirtualDisk vd = VirtualDiskManager.IT.getVirtualDisk(key);
       if ( vd == null )
-        throw new CommandFailedException("There is no virtual disk " + vd_num );
+        throw new CommandFailedException("There is no virtual disk " + key );
         
       System.out.println("  name: " + vd.getName());
       System.out.println("   key: " + vd.getKey());
-      System.out.println("  size: " + Library.format_size(vd.getSize()*Settings.SECTOR_SIZE,8,1));
+      System.out.println("  size: " + Library.formatSize(vd.getSize()*Settings.SECTOR_SIZE,8,true));
       if ( vd.getExpiry() != null )
         System.out.println("expiry: " + vd.getExpiry());
       System.out.println();
  
-      Iterator i = vd.iterator();
+      Iterator i = vd.extents();
       System.out.println("  disk       offset         size");
       while (i.hasNext()) {
         Extent e = (Extent) i.next();
-        System.out.println( Library.format(e.getDisk(), 6, 0) + " "
-                          + Library.format(e.getOffset(), 12, 0) + " "
-                          + Library.format(e.getSize(), 12, 0) );
+        System.out.println( Library.format(e.getDisk(), 6, false) + " "
+                          + Library.format(e.getOffset(), 12, false) + " "
+                          + Library.format(e.getSize(), 12, false) );
       }
     }
   }
index 4a2a9c811c8cc208f26504d147d08f0fd4a6fb69..9dc8c19b85f75cf06256310a00428306c8e27dbe 100644 (file)
@@ -15,8 +15,8 @@ public class CommandPartitionAdd extends Command {
   }
 
   public String execute() throws CommandFailedException {
-    VirtualDiskManager.it.add_xeno_partition(partition,chunksize);
-    PartitionManager.it.add_xeno_partition(partition);
+    VirtualDiskManager.IT.addPartition(partition,chunksize);
+    PartitionManager.IT.addXenoPartition(partition);
     return "Added partition " + partition.getName();
   }
 }
index abaf4a7213d609adeed1135ea9e6e1696697d4c2..234a0880d6f68a3243c03dd97013114114f612ef 100644 (file)
@@ -12,86 +12,95 @@ import java.util.StringTokenizer;
  * to modes.
  */
 public class CommandPhysicalList extends Command {
-  private int domain_id;
-  private Defaults d;
-  private Map map = new HashMap();
+    private int domain_id;
+    private Defaults d;
+    private Map map = new HashMap();
 
-  /**
-   * Constructor for CommandDomainList.
-   * @param d Defaults object to use.
-   */
-  public CommandPhysicalList(Defaults d, int domain_id) {
-    this.d = d;
-    this.domain_id = domain_id;
-  }
+    /**
+     * Constructor for CommandDomainList.
+     * @param d Defaults object to use.
+     */
+    public CommandPhysicalList(Defaults d, int domain_id) {
+        this.d = d;
+        this.domain_id = domain_id;
+    }
 
-  /**
-   * Retrieves the list of extents.
-   * @return null, call extents() to get the list.
-   */
-  public String execute() throws CommandFailedException {
-    Runtime r = Runtime.getRuntime();
-    String outline;
-    BufferedReader in;
-    String output = null;
+    /**
+     * Retrieves the list of extents.
+     * @return null, call extents() to get the list.
+     */
+    public String execute() throws CommandFailedException {
+        Runtime r = Runtime.getRuntime();
+        String outline;
+        BufferedReader in;
+        String output = null;
 
-    try {
-      Process start_p;
-      String start_cmdarray[] = new String[2];
-      int start_rc;
-      start_cmdarray[0] = d.XIToolsDir + "xi_phys_probe";
-      start_cmdarray[1] = Integer.toString( domain_id );
+        try {
+            Process start_p;
+            String start_cmdarray[] = new String[2];
+            int start_rc;
+            start_cmdarray[0] = d.XIToolsDir + "xi_phys_probe";
+            start_cmdarray[1] = Integer.toString(domain_id);
 
-      if (Settings.TEST) {
-        output = reportCommand(start_cmdarray);
-      } else {
-        start_p = r.exec(start_cmdarray);
-        start_rc = start_p.waitFor();
-        if (start_rc != 0) {
-          throw CommandFailedException.XICommandFailed("Could not get extent list", start_cmdarray);
-        }
+            if (Settings.TEST) {
+                output = reportCommand(start_cmdarray);
+            } else {
+                start_p = r.exec(start_cmdarray);
+                start_rc = start_p.waitFor();
+                if (start_rc != 0) {
+                    throw CommandFailedException.XICommandFailed(
+                        "Could not get extent list",
+                        start_cmdarray);
+                }
 
-        in =
-          new BufferedReader(new InputStreamReader(start_p.getInputStream()));
+                in =
+                    new BufferedReader(
+                        new InputStreamReader(start_p.getInputStream()));
 
-        outline = in.readLine();
-        while (outline != null) {
-          Extent extent = new Extent();
+                outline = in.readLine();
+                while (outline != null) {
+                    int disk = -1;
+                    long offset = -1;
+                    long size = -1;
+                    
+                    StringTokenizer st = new StringTokenizer(outline);
+                    if (st.hasMoreTokens()) {
+                        disk = Short.parseShort(st.nextToken(), 16);
+                    }
+                    if (st.hasMoreTokens()) {
+                        offset = Long.parseLong(st.nextToken(), 16);
+                    }
+                    if (st.hasMoreTokens()) {
+                        size = Long.parseLong(st.nextToken(), 16);
+                    }
+                    if (st.hasMoreTokens()) {
+                        String mode = st.nextToken();
+                        Extent extent = new Extent(disk,offset,size);
+                        if (mode.equals("rw"))
+                            map.put(extent, Mode.READ_WRITE);
+                        else if (mode.equals("r"))
+                            map.put(extent, Mode.READ_ONLY);
+                        else
+                            throw new CommandFailedException(
+                                "Could not parse access mode " + mode);
+                    }
 
-          StringTokenizer st = new StringTokenizer(outline);
-          if (st.hasMoreTokens()) {
-            extent.disk = Short.parseShort(st.nextToken(),16);
-          }
-          if (st.hasMoreTokens()) {
-            extent.offset = Long.parseLong(st.nextToken(),16);
-          }
-          if (st.hasMoreTokens()) {
-            extent.size = Long.parseLong(st.nextToken(),16);
-          }
-          if (st.hasMoreTokens()) {
-            String mode = st.nextToken();
-            if ( mode.equals( "rw" ) )
-              map.put( extent, Mode.READ_WRITE );
-            else if ( mode.equals ( "r" ) )
-              map.put( extent, Mode.READ_ONLY );
-            else
-              throw new CommandFailedException("Could not parse access mode " + mode);
-          }
+                    outline = in.readLine();
+                }
 
-          outline = in.readLine();
+            }
+        } catch (CommandFailedException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new CommandFailedException(
+                "Could not get extent list(" + e + ")",
+                e);
         }
 
-      }
-    } catch (CommandFailedException e) {
-      throw e;
-    } catch (Exception e) {
-      throw new CommandFailedException("Could not get extent list(" + e + ")", e);
+        return output;
     }
 
-    return output;
-  }
-  
-  public Map extents() {
-    return map;
-  }
+    public Map extents() {
+        return map;
+    }
 }
index f9b46cfd3289f0f3ac1c0a7371c901fdff394264..bdc3c774ebf8142760d1858e608f869bab358f9d 100644 (file)
@@ -20,7 +20,7 @@ public class CommandVdCreate extends Command {
   }
 
   public String execute() throws CommandFailedException {
-    VirtualDisk vd = VirtualDiskManager.it.create_virtual_disk(name,size,expiry);
+    VirtualDisk vd = VirtualDiskManager.IT.createVirtualDisk(name,size,expiry);
     if ( vd == null )
       throw new CommandFailedException( "Not enough free space to create disk" );
     return "Virtual Disk created with key: " + vd.getKey();
index 6df1a69da5252e2bf243723feede1512f61ee513..f09561dfd2235cffd6dde5a14decef0325dada1b 100644 (file)
@@ -12,7 +12,7 @@ public class CommandVdDelete extends Command {
   }
 
   public String execute() throws CommandFailedException {
-    VirtualDiskManager.it.delete_virtual_disk(key);
+    VirtualDiskManager.IT.deleteVirtualDisk(key);
     return "Deleted virtual disk " + key;
   }
 }
index 35a7d8f05896cde7f5effaa70dc0290a101ecfc5..291e709446833c85d141a6da91f6130b96bb7abc 100644 (file)
@@ -9,7 +9,7 @@ public class CommandVdRefresh extends Command {
   /**
    * Constructor for CommandVdRefresh.
    * @param key Key to refresh.
-   * @param expiry New expiry.
+   * @param expiry New expiry (null for no expiry).
    */
   public CommandVdRefresh(String key, Date expiry) {
     this.key = key;
@@ -17,7 +17,10 @@ public class CommandVdRefresh extends Command {
   }
 
   public String execute() throws CommandFailedException {
-    VirtualDiskManager.it.refresh_virtual_disk(key,expiry);
+    VirtualDisk vd = VirtualDiskManager.IT.getVirtualDisk(key);
+    if ( vd == null )
+      throw new CommandFailedException( "No such virtual disk " + key );
+    vd.refreshExpiry(expiry);
     return "Refreshed virtual disk " + key;
   }
 }
index cd653a9ed9270ed24d67a6b4bd75a7924cdee13e..3e56f31d23d2f4dfab2b4eb9f5e40cc1721486e9 100644 (file)
@@ -5,83 +5,61 @@
 
 package org.xenoserver.control;
 
-public class
-Extent
-{
-  int disk;
-  long offset;                                           /* offset into disk */
-  long size;                      /* size of this extent in 512 byte sectors */
-
-  public int
-  getDisk()
-  {
-    return disk;
-  }
-
-  public long
-  getOffset()
-  {
-    return offset;
-  }
-
-  public long
-  getSize()
-  {
-    return size;
-  }
-  
-  public int
-  getMajor()
-  {
-    return disk >> 8;
-  }
-  
-  public int
-  getMinor()
-  {
-    return disk & 0xFF;
-  }
-  
-  public int hashCode() {
-    final int PRIME = 1000003;
-    int result = 0;
-    result = PRIME * result + disk;
-    result = PRIME * result + (int) (offset >>> 32);
-    result = PRIME * result + (int) (offset & 0xFFFFFFFF);
-    result = PRIME * result + (int) (size >>> 32);
-    result = PRIME * result + (int) (size & 0xFFFFFFFF);
-
-    return result;
-  }
+/**
+ * Represents an extent on physical disk.
+ */
+public class Extent {
+    /** Disk number; 16-bit major:minor pair with no partition number. */
+    private int disk;
+    /** Offset into disk in sectors. */
+    private long offset;
+    /** Size of extent in sectors. */
+    private long size;
 
-  public boolean equals(Object oth) {
-    if (this == oth) {
-      return true;
+    /**
+     * Constructor for Extent.
+     * @param disk Disk number.
+     * @param offset Offset into disk.
+     * @param size Size of extent.
+     */
+    Extent(int disk, long offset, long size) {
+        this.disk = disk;
+        this.offset = offset;
+        this.size = size;
     }
 
-    if (oth == null) {
-      return false;
+    /**
+     * @return Disk number.
+     */
+    public int getDisk() {
+        return disk;
     }
 
-    if (oth.getClass() != getClass()) {
-      return false;
+    /**
+     * @return Offset into disk.
+     */
+    public long getOffset() {
+        return offset;
     }
 
-    Extent other = (Extent) oth;
-
-    if (this.disk != other.disk) {
-      return false;
+    /**
+     * @return Size of extent.
+     */
+    public long getSize() {
+        return size;
     }
 
-    if (this.offset != other.offset) {
-      return false;
+    /**
+     * @return Major number of disk.
+     */
+    public int getMajor() {
+        return disk >> 8;
     }
 
-    if (this.size != other.size) {
-      return false;
+    /**
+     * @return Minor number of disk, not including partition.
+     */
+    public int getMinor() {
+        return disk & 0xFF;
     }
-
-    return true;
-  }
-
 }
index 79c2385ef854962d94b649a841a8dd99012bbc49..90108dd250c4da18922a622b6c555daf0809cbdc 100644 (file)
@@ -3,58 +3,77 @@ package org.xenoserver.control;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
-public class InetAddressPattern
-{
-  InetAddress base;
-  boolean addDom;
+/**
+ * This utility class expands configuration file patterns.
+ */
+public class InetAddressPattern {
+    /** The base InetAddress for this pattern. */
+    private InetAddress base;
+    /** If true, add the domain number to the base address. */
+    private boolean addDom;
 
-  static InetAddressPattern parse (String t)
-  {
-    InetAddressPattern result = new InetAddressPattern ();
-    char[] ca = t.toCharArray ();
-    int len = ca.length;
+    /**
+     * Parse a pattern string into an InetAddressPattern.
+     * @param t The pattern string.
+     * @return The parsed pattern object.
+     */
+    static InetAddressPattern parse(String t) {
+        InetAddressPattern result = new InetAddressPattern();
+        char[] ca = t.toCharArray();
+        int len = ca.length;
 
-    try {
-      if (len == 0) {
-       result.base = null;
-       result.addDom = false;
-      } else if (ca[len - 1] == '+') {
-       result.base = InetAddress.getByName(t.substring(0, len - 1));
-       result.addDom = true;
-      } else {
-       result.base = InetAddress.getByName(t);
-       result.addDom = false;
-      }
-    } catch (UnknownHostException uhe) {
-      result.base = null;
-      result.addDom = false;
-    }
+        try {
+            if (len == 0) {
+                result.base = null;
+                result.addDom = false;
+            } else if (ca[len - 1] == '+') {
+                result.base = InetAddress.getByName(t.substring(0, len - 1));
+                result.addDom = true;
+            } else {
+                result.base = InetAddress.getByName(t);
+                result.addDom = false;
+            }
+        } catch (UnknownHostException uhe) {
+            result.base = null;
+            result.addDom = false;
+        }
 
-    return result;
-  }
+        return result;
+    }
 
-  public String resolve (int domain_id) {
-    byte b[] = base.getAddress ();
-    if (addDom) {
-      if (((int)b[3]) + domain_id > 255) {
-       if (((int)b[2]) + domain_id > 255) {
-         if (((int)b[1]) + domain_id > 255) {
-           b[0] ++;
-         }
-         b[1] ++;
-       }
-       b[2] ++;
-      }
-      b[3] += domain_id;
+    /**
+     * Resolve the pattern for the given domain.
+     * @param domain_id The domain ID.
+     * @return The resolved string.
+     */
+    String resolve(int domain_id) {
+        byte[] b = base.getAddress();
+        if (addDom) {
+            if (((int) b[3]) + domain_id > 255) {
+                if (((int) b[2]) + domain_id > 255) {
+                    if (((int) b[1]) + domain_id > 255) {
+                        b[0]++;
+                    }
+                    b[1]++;
+                }
+                b[2]++;
+            }
+            b[3] += domain_id;
+        }
+        return ""
+            + (b[0] + (b[0] < 0 ? 256 : 0))
+            + "."
+            + (b[1] + (b[1] < 0 ? 256 : 0))
+            + "."
+            + (b[2] + (b[2] < 0 ? 256 : 0))
+            + "."
+            + (b[3] + (b[3] < 0 ? 256 : 0));
     }
-    return "" + 
-      (b[0] + (b[0] < 0 ? 256 : 0)) + "." + 
-      (b[1] + (b[1] < 0 ? 256 : 0)) + "." + 
-      (b[2] + (b[2] < 0 ? 256 : 0)) + "." + 
-      (b[3] + (b[3] < 0 ? 256 : 0));
-  }
 
-  public String toString () {
-    return "[" + base + (addDom ? "+dom_id" : "") + "]";
-  }
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return "[" + base + (addDom ? "+dom_id" : "") + "]";
+    }
 }
index d79e01aef50d3ab427a1b3644e6ee6f9bb77e49f..eb9021894087cf97e017c631bc0e9b41a585700b 100644 (file)
 
 package org.xenoserver.control;
 
-public class
-Library
-{
-  /*
-   * convert a number to a fixed width string
-   */
-  public static String
-  format (long input, int width, int prefix)
-  {
-    String sss = Long.toString(input);
-    String space = "                                ";
-
-    if (width < sss.length())
-    {
-      width = sss.length();
-    }
+/**
+ * Library functions.
+ */
+public class Library {
+    /**
+     * Convert a number to a fixed width string.
+     * @param input The number to convert.
+     * @param width The width desired.
+     * @param leftAlign True to left-align the number.
+     * @return The formatted string.
+     */
+    public static String format(long input, int width, boolean leftAlign) {
+        String sss = Long.toString(input);
+        String space = "                                ";
 
-    if (prefix == 0)
-    {
-      return space.substring(0, width - sss.length()) + sss;
-    }
-    else
-    {
-      return sss + space.substring(0, width - sss.length());
-    }
-  }
-
-  /*
-   * convert a string to a fixed width string
-   */
-  public static String
-  format (String input, int width, int prefix)
-  {
-    String space = "                                ";
-
-    if (width < input.length())
-    {
-      width = input.length();
-    }
+        if (width < sss.length()) {
+            width = sss.length();
+        }
 
-    if (prefix == 0)
-    {
-      return space.substring(0, width - input.length()) + input;
-    }
-    else
-    {
-      return input + space.substring(0, width - input.length());
-    }
-  }
-
-  /*
-   * convert a number (string format) into 
-   * the corresponding integer value.
-   */
-  public static long
-  parse_size(String size)
-  {
-    String substring = size;
-    int    suffix = 1;
-    long   value = 0;
-
-    if (size == null)
-    {
-      return 0;
+        if (leftAlign) {
+            return sss + space.substring(0, width - sss.length());
+        } else {
+            return space.substring(0, width - sss.length()) + sss;
+        }
     }
 
-    if ((substring = check(size, 'm')) != null)
-    {
-      suffix = 1024 * 1024;
-    }
-    else if ((substring = check(size, 'M')) != null)
-    {
-      suffix = 1024 * 1024;
-    }
-    else if ((substring = check(size, 'k')) != null)
-    {
-      suffix = 1024;
-    }
-    else if ((substring = check(size, 'K')) != null)
-    {
-      suffix = 1024;
-    }
-    else if ((substring = check(size, 'g')) != null)
-    {
-      suffix = 1024 * 1024 * 1024;
-    }
-    else if ((substring = check(size, 'G')) != null)
-    {
-      suffix = 1024 * 1024 * 1024;
-    }
-    else
-    {
-      substring = size;
-    }
+    /**
+     * Convert a string to a fixed-width string.
+     * @param input Input string.
+     * @param width Width desired.
+     * @param leftAlign True to left-align the string.
+     * @return The formatted string.
+     */
+    public static String format(String input, int width, boolean leftAlign) {
+        String space = "                                ";
 
-    try
-    {
-      value = Long.decode(substring).longValue() * suffix;
-    }
-    catch (NumberFormatException e)
-    {
-      value = 0;
+        if (width < input.length()) {
+            width = input.length();
+        }
+
+        if (leftAlign) {
+            return input + space.substring(0, width - input.length());
+        } else {
+            return space.substring(0, width - input.length()) + input;
+        }
     }
 
-    return value;
-  }
+    /**
+     * Parse a size which may have a k/m/g suffix into a number.
+     * @param size The size string to parse.
+     * @return The equivalent number.
+     */
+    public static long parseSize(String size) {
+        String substring = size;
+        int suffix = 1;
+        long value = 0;
 
-  public static String
-  check(String size, char suffix)
-  {
-    int index = size.indexOf(suffix);
+        if (size == null) {
+            return 0;
+        }
 
-    if (index != -1)
-    {
-      return size.substring(0, index);
-    }
-    else
-    {
-      return null;
+        if ((substring = check(size, 'm')) != null) {
+            suffix = 1024 * 1024;
+        } else if ((substring = check(size, 'M')) != null) {
+            suffix = 1024 * 1024;
+        } else if ((substring = check(size, 'k')) != null) {
+            suffix = 1024;
+        } else if ((substring = check(size, 'K')) != null) {
+            suffix = 1024;
+        } else if ((substring = check(size, 'g')) != null) {
+            suffix = 1024 * 1024 * 1024;
+        } else if ((substring = check(size, 'G')) != null) {
+            suffix = 1024 * 1024 * 1024;
+        } else {
+            substring = size;
+        }
+
+        try {
+            value = Long.decode(substring).longValue() * suffix;
+        } catch (NumberFormatException e) {
+            value = 0;
+        }
+
+        return value;
     }
-  }
-  
-  /**
-   * Formats a number of bytes in whichever way makes most sense based
-   * on magnitude and width.
-   * 
-   * @param size Number of bytes.
-   * @param width Width of field - at least 5, plz.
-   * @param prefix Set to 1 for left justify
-   * @return The formatted string.
-   */
-  public static String format_size(long size,int width,int prefix) {
-    char[] suffixes = { ' ', 'k', 'M', 'G' };
-    int suffix = 0;
-    long before = size;
-    float after = 0;
-    
-    while ( before > 10000 ) {
-      after = ((float)(before % 1024)) / 1024;
-      before /= 1024;
-      suffix++; 
+
+    /**
+     * Check if the given size has the specified suffix.
+     * @param size Size string.
+     * @param suffix Test suffix.
+     * @return Number part of string, or null if suffix does not match.
+     */
+    private static String check(String size, char suffix) {
+        int index = size.indexOf(suffix);
+
+        if (index != -1) {
+            return size.substring(0, index);
+        } else {
+            return null;
+        }
     }
-    
-    StringBuffer num = new StringBuffer(width);
-    num.append( Long.toString( before ) );
-    if ( after != 0 ) {
-      int space = width - num.length() - 2;
-      if ( space > 0 ) {
-        num.append( '.' );
-        if ( space > 3 )
-          space = 3;
-        num.append( Integer.toString( (int) (after * Math.pow(10,space))));
-      }
+
+    /**
+     * Formats a number of bytes in whichever way makes most sense based
+     * on magnitude and width.
+     * 
+     * @param size Number of bytes.
+     * @param width Width of field - at least 5, plz.
+     * @param leftAlign True for left-align.
+     * @return The formatted string.
+     */
+    public static String formatSize(long size, int width, boolean leftAlign) {
+        char[] suffixes = { ' ', 'k', 'M', 'G' };
+        int suffix = 0;
+        long before = size;
+        float after = 0;
+
+        while (before > 10000) {
+            after = ((float) (before % 1024)) / 1024;
+            before /= 1024;
+            suffix++;
+        }
+
+        StringBuffer num = new StringBuffer(width);
+        num.append(Long.toString(before));
+        if (after != 0) {
+            int space = width - num.length() - 2;
+            if (space > 0) {
+                num.append('.');
+                if (space > 3) {
+                    space = 3;
+                }
+                num.append(
+                    Integer.toString((int) (after * Math.pow(10, space))));
+            }
+        }
+        num.append(suffixes[suffix]);
+
+        return format(num.toString(), width, leftAlign);
     }
-    num.append( suffixes[suffix] );
-    
-    return format(num.toString(),width,prefix);
-  }
 }
index 5f2ea4d485b8b33a87d6ec3a5518ddd68743eec9..e9621604a1c2c18886d956f926bd23de262c3a9d 100644 (file)
@@ -7,16 +7,30 @@
 
 package org.xenoserver.control;
 
-public class 
-Mode 
-{
-  private final String name;
+/**
+ * Enumeration to represent an access mode.
+ */
+public class Mode {
+    /** name of this mode */
+    private final String name;
 
-  private Mode(String name) { this.name = name; }
+    /**
+     * Construct a mode
+     * @param name Name to use.
+     */
+    private Mode(String name) {
+        this.name = name;
+    }
 
-  public String toString()  { return name; }
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return name;
+    }
 
-  public static final Mode READ_ONLY  = new Mode("ro");
-  public static final Mode READ_WRITE = new Mode("rw");
+    /** Single read-only mode instance. */
+    public static final Mode READ_ONLY = new Mode("ro");
+    /** Single read-write mode instance. */
+    public static final Mode READ_WRITE = new Mode("rw");
 }
-
index 85ea7e372840698e04cd8f5eede763d8bd723241..510e266813eb493f14d58c3b537d497914af5367 100644 (file)
@@ -7,184 +7,179 @@ package org.xenoserver.control;
 
 import java.io.PrintWriter;
 
-public class
-Partition
-{
-  int major;
-  int minor;
-  long blocks;
-  long start_sect;
-  long nr_sects;
-  String name;
-  boolean xeno;
-
-  Partition
-  duplicate ()
-  {
-    Partition p = new Partition();
-
-    p.major = major;
-    p.minor = minor;
-    p.blocks = blocks;
-    p.start_sect = start_sect;
-    p.nr_sects = nr_sects;
-    p.name = name;
-    p.xeno = xeno;
-
-    return p;
-  }
-
-  void
-  dump_xml(PrintWriter out)
-  {
-    out.println ("  <partition>\n" +
-                "    <major>" + major + "</major>\n" +
-                "    <minor>" + minor + "</minor>\n" +
-                "    <blocks>" + blocks + "</blocks>\n" +
-                "    <start_sect>" + start_sect + "</start_sect>\n" +
-                "    <nr_sects>" + nr_sects + "</nr_sects>\n" +
-                "    <name>" + name + "</name>\n" +
-                "  </partition>");
-  }
-
-  public int
-  getMajor()
-  {
-    return major;
-  }
-
-  public int
-  getMinor()
-  {
-    return minor;
-  }
-
-  public long
-  getBlocks()
-  {
-    return blocks;
-  }
-  
-  public long
-  getStartSect()
-  {
-    return start_sect;
-  }
-
-  public long
-  getNumSects()
-  {
-    return nr_sects;
-  }
-  
-  public String
-  getName()
-  {
-    return name;
-  }
-
-  public boolean
-  getIsXeno()
-  {
-    return xeno;
-  }
-
-  public int hashCode() {
-    final int PRIME = 1000003;
-    int result = 0;
-    result = PRIME * result + major;
-    result = PRIME * result + minor;
-    result = PRIME * result + (int) (blocks >>> 32);
-    result = PRIME * result + (int) (blocks & 0xFFFFFFFF);
-    result = PRIME * result + (int) (start_sect >>> 32);
-    result = PRIME * result + (int) (start_sect & 0xFFFFFFFF);
-    result = PRIME * result + (int) (nr_sects >>> 32);
-    result = PRIME * result + (int) (nr_sects & 0xFFFFFFFF);
-    if (name != null) {
-      result = PRIME * result + name.hashCode();
+/**
+ * Represents a single real partition.
+ */
+public class Partition {
+    /** Major device number as seen by Linux. */
+    private int major;
+    /** Minor device number as seen by Linux. */
+    private int minor;
+    /** Number of blocks in the partition. */
+    private long blocks;
+    /** Start sector of the partition. */
+    private long start_sect;
+    /** Number of sectors in the partition. */
+    private long nr_sects;
+    /** Name of the partition. */
+    private String name;
+    /** True if this partition is a XenoPartition. */
+    private boolean xeno;
+
+    /**
+     * Mark this partition as a XenoPartition.
+     */
+    void makeXeno() {
+        xeno = true;
     }
 
-    return result;
-  }
+    /**
+     * Constructor for Partition.
+     * @param major Major number
+     * @param minor Minor number
+     * @param blocks Size in blocks
+     * @param start_sect Start sector
+     * @param nr_sects Number of sectors
+     * @param name Name of partition
+     * @param xeno True if XenoPartition
+     */
+    Partition(
+        int major,
+        int minor,
+        long blocks,
+        long start_sect,
+        long nr_sects,
+        String name,
+        boolean xeno) {
+        this.major = major;
+        this.minor = minor;
+        this.blocks = blocks;
+        this.start_sect = start_sect;
+        this.nr_sects = nr_sects;
+        this.name = name;
+        this.xeno = xeno;
+    }
 
-  public boolean equals(Object oth) {
-    if (this == oth) {
-      return true;
+    /**
+     * Dump this partition as XML.
+     * @param out The writer to dump to.
+     */
+    void dumpAsXML(PrintWriter out) {
+        out.println(
+            "  <partition>\n"
+                + "    <major>"
+                + major
+                + "</major>\n"
+                + "    <minor>"
+                + minor
+                + "</minor>\n"
+                + "    <blocks>"
+                + blocks
+                + "</blocks>\n"
+                + "    <start_sect>"
+                + start_sect
+                + "</start_sect>\n"
+                + "    <nr_sects>"
+                + nr_sects
+                + "</nr_sects>\n"
+                + "    <name>"
+                + name
+                + "</name>\n"
+                + "  </partition>");
     }
 
-    if (oth == null) {
-      return false;
+    /**
+     * @return Major device number.
+     */
+    public int getMajor() {
+        return major;
     }
 
-    if (oth.getClass() != getClass()) {
-      return false;
+    /**
+     * @return Minor device number.
+     */
+    public int getMinor() {
+        return minor;
     }
 
-    Partition other = (Partition) oth;
+    /**
+     * @return Number of blocks.
+     */
+    public long getBlocks() {
+        return blocks;
+    }
 
-    if (this.major != other.major) {
-      return false;
+    /**
+     * @return Starting sector.
+     */
+    public long getStartSect() {
+        return start_sect;
     }
 
-    if (this.minor != other.minor) {
-      return false;
+    /**
+     * @return Number of sectors.
+     */
+    public long getNumSects() {
+        return nr_sects;
     }
 
-    if (this.blocks != other.blocks) {
-      return false;
+    /**
+     * @return Name of partition.
+     */
+    public String getName() {
+        return name;
     }
 
-    if (this.start_sect != other.start_sect) {
-      return false;
+    /**
+     * @return True if this is a XenoPartition.
+     */
+    public boolean isXeno() {
+        return xeno;
     }
 
-    if (this.nr_sects != other.nr_sects) {
-      return false;
+    /**
+     * Is this partition identical to the other?
+     * @param other Other partition to compare to.
+     * @return True if they are identical.
+     */
+    public boolean identical(Partition other) {
+        return this.major == other.major
+            && this.minor == other.minor
+            && this.blocks == other.blocks
+            && this.start_sect == other.start_sect
+            && this.nr_sects == other.nr_sects
+            && this.name.equals(other.name);
     }
-    if (this.name == null) {
-      if (other.name != null) {
-        return false;
-      }
-    } else {
-      if (!this.name.equals(other.name)) {
-        return false;
-      }
+
+    /**
+     * @return An Extent covering this partiton.
+     */
+    public Extent toExtent() {
+        return new Extent(getDisk(),start_sect,nr_sects);
     }
 
-    return true;
-  }
-
-  /**
-   * @return An Extent covering this partiton.
-   */
-  public Extent toExtent()
-  {
-    Extent e = new Extent();
-    // Build 16-bit disk number.. high 8 bits are the major
-    e.disk = major << 8;
-    // Low 8 bits are the minor, but bottom 5 need to be cleared
-    // as they are the partition number, not the disk number
-    e.disk |= ( minor & 0xE0 );
-    e.offset = start_sect;
-    e.size = nr_sects;
-    return e;
-  }
-  
-  /**
-   * @param e Extent to compare this partition to.
-   * @return True if this partition covers the same disk area as the given extent.
-   */
-  public boolean matchesExtent( Extent e )
-  {
-    if ( e.getMajor() != major )
-      return false;
-    if ( e.getMinor() != minor )
-      return false;
-    if ( e.offset != start_sect )
-      return false;
-    if ( e.size != nr_sects )
-      return false;
-      
-    return true;
-  }
+    /**
+     * @param e Extent to compare this partition to.
+     * @return True if this partition covers the same disk area as the given extent.
+     */
+    public boolean matchesExtent(Extent e) {
+        return e.getDisk() == getDisk()
+            && e.getOffset() == start_sect
+            && e.getSize() == nr_sects;
+    }
+    
+    /**
+     * @return Disk number for this partition.
+     */
+    public int getDisk() {
+        if ( name.startsWith("hd") ) {
+            // High 8 bits are major, low 8 bits are minor, with bottom 6 clear
+            return (major << 8) | (minor & 0xC0); 
+        } else if ( name.startsWith("sd") ) {
+            // High 8 bits are major, low 8 bits are minor, with bottom 4 clear
+            return (major << 8) | (minor & 0xF0);
+        } else {
+            throw new IllegalArgumentException("Don't know how to convert " + name + "into a disk number");
+        }
+    }
 }
index 2c936367622a40b6a6ed7e1f09808c8be0f81f28..b638e14922c34d0e8bc5ee141fbbf09f4cc89fed 100644 (file)
@@ -17,170 +17,155 @@ import java.util.Vector;
  * PartitionManager manages the partitions on the machine. It is a Singleton
  * which automatically initialises itself on first class reference.
  */
-public class
-PartitionManager
-{
-  static final String proc_template =
-    "major minor  #blocks  start_sect   nr_sects name";
-    
-  public static final PartitionManager it = new PartitionManager(Settings.PARTITIONS_FILE);
-    
-  Vector partition_map;
-
-  /*
-   * Initialize partition manager with source file.
-   * Normally we read from /proc/partitions, but we can
-   * specify an alternative file for debugging
-   */
-  private PartitionManager (String filename)
-  {
-    String str;
-    BufferedReader in;
-
-    partition_map = new Vector(100,10);
-
-    try
-    {
-      in = new BufferedReader(new FileReader(filename));
-
-      str = in.readLine();                                  /* skip headings */
-      if (str.length() < proc_template.length() ||
-         !str.substring(0, proc_template.length()).equals(proc_template))
-      {
-       System.err.println ("Error: Incorrect /proc/partitions.");
-       System.err.println ("       Is this Xeno?");
-       System.exit (1);
-      }
-
-      str = in.readLine();                                /* skip blank line */
-
-      str = in.readLine();
-      while (str != null)
-      {
-       Partition partition = new Partition();
-
-       partition.major = Integer.parseInt(str.substring(0,5).trim());
-       partition.minor = Integer.parseInt(str.substring(5,10).trim());
-       partition.blocks = Integer.parseInt(str.substring(10,21).trim());
-       partition.start_sect = Integer.parseInt(str.substring(21,32).trim());
-       partition.nr_sects = Integer.parseInt(str.substring(32,43).trim());
-       partition.name = str.substring(43).trim();
-       partition.xeno = false;
-
-       partition_map.add(partition);
-       str = in.readLine();
-      }
+public class PartitionManager {
+    /** The proc header string, used to check that this is a suitable proc file. */
+    private static final String PROC_TEMPLATE =
+        "major minor  #blocks  start_sect   nr_sects name";
+
+    /** The single PartitionManager reference. */
+    public static final PartitionManager IT =
+        new PartitionManager(Settings.PARTITIONS_FILE);
+
+    /** The list of partitions. */
+    private Vector partition_map;
+
+    /**
+     * Initialize partition manager with source file.
+     * Normally we read from /proc/partitions, but we can
+     * specify an alternative file for debugging.
+     * @param filename The file to read partition data from.
+     */
+    private PartitionManager(String filename) {
+        String str;
+        BufferedReader in;
+
+        partition_map = new Vector(100, 10);
+
+        try {
+            in = new BufferedReader(new FileReader(filename));
+
+            str = in.readLine(); /* skip headings */
+            if (str.length() < PROC_TEMPLATE.length()
+                || !str.substring(0, PROC_TEMPLATE.length()).equals(
+                    PROC_TEMPLATE)) {
+                System.err.println("Error: Incorrect /proc/partitions.");
+                System.err.println("       Is this Xeno?");
+                System.exit(1);
+            }
+
+            str = in.readLine(); /* skip blank line */
+
+            str = in.readLine();
+            while (str != null) {
+                Partition partition =
+                    new Partition(
+                        Integer.parseInt(str.substring(0, 5).trim()),
+                        Integer.parseInt(str.substring(5, 10).trim()),
+                        Integer.parseInt(str.substring(10, 21).trim()),
+                        Integer.parseInt(str.substring(21, 32).trim()),
+                        Integer.parseInt(str.substring(32, 43).trim()),
+                        str.substring(43).trim(),
+                        false);
+
+                partition_map.add(partition);
+                str = in.readLine();
+            }
+        } catch (IOException io) {
+            System.err.println(
+                "PartitionManager: error reading partition file ["
+                    + filename
+                    + "]");
+            System.err.println(io);
+        }
     }
-    catch (IOException io)
-    {
-      System.err.println ("PartitionManager: error reading partition file [" 
-                         + filename + "]");
-      System.err.println (io);
+
+    /**
+     * Find a partition with the specified name.
+     * @param name The name to search for.
+     * @return The partition found, or null if no such partition.
+     */
+    public Partition getPartition(String name) {
+        Partition partition = null;
+        for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+            partition = (Partition) e.nextElement();
+            if (partition.getName().equals(name)) {
+                return partition;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Finds the partition that matches the given extent, if any.
+     * @param extent The extent to compare to.
+     * @return The first matching partition, or null if none.
+     */
+    public Partition getPartition(Extent extent) {
+        Partition partition = null;
+        for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+            partition = (Partition) e.nextElement();
+            if (partition.matchesExtent(extent)) {
+                return partition;
+            }
+        }
+        return null;
     }
-  }
-
-  public Partition
-  get_partition (String name)
-  {
-    Partition partition = null;
-    for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) 
-    {
-      partition = (Partition) e.nextElement();
-      if (partition.name.equals(name))
-      {
-  return partition;
-      }
+    
+    /**
+     * Find the ith partition in the partition list.
+     * @param i Index number.
+     * @return The partition, or null if out of range.
+     */
+    public Partition getPartition(int i) {
+        if ( i >= partition_map.size() ) {
+          return null;
+        }
+        return (Partition) partition_map.elementAt( i );
     }
-    return null;
-  }
-
-  /**
-   * Finds the partition that matches the given extent, if any.
-   * @param extent The extent to compare to.
-   * @return The first matching partition, or null if none.
-   */
-  public Partition
-  get_partition (Extent extent)
-  {
-    Partition partition = null;
-    for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) 
-    {
-      partition = (Partition) e.nextElement();
-      if (partition.matchesExtent(extent))
-      {
-  return partition;
-      }
+
+    /**
+     * Adds the given partition as a XenoPartition.
+     * @param p The partition to add.
+     */
+    void addXenoPartition(Partition p) {
+        for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+            Partition partition = (Partition) e.nextElement();
+            if (partition.identical(p)) {
+                partition.makeXeno();
+            }
+        }
     }
-    return null;
-  }
-
-  Partition
-  get_partition (int index)
-  {
-    return (Partition) partition_map.get(index);
-  }
-
-  void
-  add_xeno_partition (Partition p)
-  {
-    for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) 
-    {
-      Partition partition = (Partition) e.nextElement();
-      if (partition.equals(p))
-      {
-       partition.xeno = true;
-      }
+
+    /**
+     * Dump the XenoPartition list as XML.
+     * @param out Writer to dump to.
+     */
+    void dumpAsXML(PrintWriter out) {
+        out.println("<partitions>");
+        for (Enumeration e = partition_map.elements(); e.hasMoreElements();) {
+            Partition partition = (Partition) e.nextElement();
+            if (partition.isXeno()) {
+                partition.dumpAsXML(out);
+            }
+        }
+
+        out.println("</partitions>");
+
+        return;
     }
-  }
-
-  /*
-   * dump the xeno partition list as xml
-   */
-  void
-  dump_xml (PrintWriter out)
-  {
-    out.println("<partitions>");
-    for (Enumeration e = partition_map.elements() ; e.hasMoreElements() ;) 
-    {
-      Partition partition = (Partition) e.nextElement();
-      if (partition.xeno == true)
-      {
-       partition.dump_xml(out);
-      }
+
+    /**
+     * @return The number of partitions. 
+     */
+    public int getPartitionCount() {
+        return partition_map.size();
     }
 
-    out.println("</partitions>");
-
-    return;
-  }
-
-  /**
-   * get the number of partitions 
-   */
-
-  int
-  getPartitionCount ()
-  {
-    return partition_map.size();
-  }
-
-  /**
-   * get the details about a particular partition
-   *
-   */
-  Partition
-  getPartition (int index)
-  {
-    Partition partition = (Partition) partition_map.get(index);
-    return partition;
-  }
-  /**
-   * Get an iterator over all the partitions.
-   * @return An iterator over Partition objects.
-   */
-  public Iterator iterator()
-  {
-    return partition_map.iterator();
-  }
+    /**
+     * Get an iterator over all the partitions.
+     * @return An iterator over Partition objects.
+     */
+    public Iterator iterator() {
+        return partition_map.iterator();
+    }
 }
index a51a7212a6487368e1f63abc153dbce1bf9b33e3..4d9ca628cc3237f75bdeec0214ad937142721391 100644 (file)
@@ -7,38 +7,63 @@ import java.util.StringTokenizer;
  * The Settings class is a repository for global settings such as the IP of
  * the machine and the location of the defaults file.
  */
-public final class Settings
-{
-  public static final String DEFAULTS_FILE = System.getProperty ("DEFAULTS_FILE", "domctl.xml");
-  public static final String DEFAULTS_PATH = System.getProperty ("DEFAULTS_PATH", ".:/etc:/var/lib/xen");
-  public static final String LOCAL_IP = System.getProperty ("LOCAL_IP");
-  public static final String LOCAL_MASK = System.getProperty ("LOCAL_MASK");
-  public static final String LOCAL_GW = System.getProperty ("LOCAL_ROUTE");
-  public static final boolean TEST = (System.getProperty ("TEST") != null);
-  public static final String XI_HELPER = System.getProperty ("XI_HELPER", "xi_helper");
-  public static final String PARTITIONS_FILE = System.getProperty("PARTITIONS_FILE", "/proc/partitions");
-  public static final String STATE_INPUT_FILE = System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml");
-  public static final String STATE_OUTPUT_FILE = System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml");
-  public static final int SECTOR_SIZE = Integer.parseInt( System.getProperty("SECTOR_SIZE", "512") );
+public final class Settings {
+    /** Filename for the defaults file. */
+    public static final String DEFAULTS_FILE =
+        System.getProperty("DEFAULTS_FILE", "domctl.xml");
+    /** Path to search for the defaults file. */
+    public static final String DEFAULTS_PATH =
+        System.getProperty("DEFAULTS_PATH", ".:/etc:/var/lib/xen");
+    /** IP address of domain 0. */
+    public static final String LOCAL_IP = System.getProperty("LOCAL_IP");
+    /** Network mask of domain 0. */
+    public static final String LOCAL_MASK = System.getProperty("LOCAL_MASK");
+    /** Gateway of domain 0. */
+    public static final String LOCAL_GW = System.getProperty("LOCAL_ROUTE");
+    /** If set, do not call any xi_ commands, just print their command lines. */
+    public static final boolean TEST = (System.getProperty("TEST") != null);
+    /** Name of xi_helper utility. */
+    public static final String XI_HELPER =
+        System.getProperty("XI_HELPER", "xi_helper");
+    /** File to parse to get partition info. */
+    public static final String PARTITIONS_FILE =
+        System.getProperty("PARTITIONS_FILE", "/proc/partitions");
+    /** File to load virtual disk state from. */
+    public static final String STATE_INPUT_FILE =
+        System.getProperty("STATE_INPUT_FILE", "/var/lib/xen/vdstate.xml");
+    /** File to save virtual disk state to. */
+    public static final String STATE_OUTPUT_FILE =
+        System.getProperty("STATE_OUTPUT_FILE", "/var/lib/xen/vdstate.xml");
+    /** Size of a sector in bytes. */
+    public static final int SECTOR_SIZE =
+        Integer.parseInt(System.getProperty("SECTOR_SIZE", "512"));
 
-  public static File getDefaultsFile() {
-    StringTokenizer tok = new StringTokenizer (DEFAULTS_PATH, ":");
-    File result = null;
-    File probe;
+    /**
+     * Search for the defaults file in the path configured in DEFAULTS_PATH.
+     * @return Reference to the defaults file.
+     */
+    public static File getDefaultsFile() {
+        StringTokenizer tok = new StringTokenizer(DEFAULTS_PATH, ":");
+        File result = null;
+        File probe;
 
-    while (tok.hasMoreTokens ()) {
-      String probe_dir = tok.nextToken ();
-      probe = new File (probe_dir, DEFAULTS_FILE);
-      if (probe.exists ()) {
-       result = probe;
-       break;
-      }
-    }
+        while (tok.hasMoreTokens()) {
+            String probe_dir = tok.nextToken();
+            probe = new File(probe_dir, DEFAULTS_FILE);
+            if (probe.exists()) {
+                result = probe;
+                break;
+            }
+        }
 
-    if (result == null) {
-      System.err.println ("Could not find " + DEFAULTS_FILE + " in path " + DEFAULTS_PATH);
-    }
+        if (result == null) {
+            System.err.println(
+                "Could not find "
+                    + DEFAULTS_FILE
+                    + " in path "
+                    + DEFAULTS_PATH);
+        }
 
-    return result;
-  }
+        return result;
+    }
 }
index 5df2470a915d774bcd78c5f949edc4a5770970a9..111a5271fae6572a0af2fa2624f1a2c3bca0699a 100644 (file)
@@ -1,59 +1,78 @@
 package org.xenoserver.control;
 
-public class StringPattern
-{
-  String base;
-  int bn;
-  boolean addDom;
-  boolean appendDom;
+/**
+ * This utility class expands configuration file patterns.
+ */
+public class StringPattern {
+    /** The base string for this pattern. */
+    private String base;
+    /** The base number for this pattern. */
+    private int bn;
+    /** If true, add the domain number to the base number and append. */
+    private boolean addDom;
+    /** If true, append the domain number to the base string. */
+    private boolean appendDom;
 
-  static StringPattern parse (String t)
-  {
-    StringPattern result = new StringPattern ();
-    char[] ca = t.toCharArray ();
-    int idx = 0;
-    int len = ca.length;
+    /**
+     * Parse a string into a pattern.
+     * @param t The pattern string to parse.
+     * @return A usable pattern object.
+     */
+    static StringPattern parse(String t) {
+        StringPattern result = new StringPattern();
+        char[] ca = t.toCharArray();
+        int idx = 0;
+        int len = ca.length;
 
-    if (len == 0) {
-      result.base = "";
-      result.bn = 0;
-      result.addDom = false;
-    } else if (ca[len - 1] == '+') {
-      idx = len - 2;
-      if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
-       while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
-         idx --;
-       }
-       result.base = t.substring(0, idx + 1);
-       result.bn = Integer.parseInt (t.substring (idx + 1, len - 1));
-       result.addDom = true;
-      } else {
-       result.base = t.substring(0, len - 1);
-       result.appendDom = true;
-      }
-    } else {
-      result.base = t;
-    }
+        if (len == 0) {
+            result.base = "";
+            result.bn = 0;
+            result.addDom = false;
+        } else if (ca[len - 1] == '+') {
+            idx = len - 2;
+            if ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+                while ((idx >= 0) && (ca[idx] >= '0') && (ca[idx] <= '9')) {
+                    idx--;
+                }
+                result.base = t.substring(0, idx + 1);
+                result.bn = Integer.parseInt(t.substring(idx + 1, len - 1));
+                result.addDom = true;
+            } else {
+                result.base = t.substring(0, len - 1);
+                result.appendDom = true;
+            }
+        } else {
+            result.base = t;
+        }
 
-    return result;
-  }
+        return result;
+    }
 
-  public String resolve (int domain_id) {
-    if (addDom) {
-      return base + (bn + domain_id);
-    } else if (appendDom) {
-      return base + domain_id;
-    } else {
-      return base;
+    /**
+     * Resolve the pattern for the given domain number.
+     * @param domain The domain number to use.
+     * @return The expanded pattern for the given domain.
+     */
+    String resolve(int domain) {
+        if (addDom) {
+            return base + (bn + domain);
+        } else if (appendDom) {
+            return base + domain;
+        } else {
+            return base;
+        }
     }
-  }
 
-  public String toString () {
-    return ("[" + 
-           base + 
-           (addDom ? "+" + bn : "") + 
-           ((addDom || appendDom) ? "+ID" : "") + 
-           "]");
-  }
+    /**
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return (
+            "["
+                + base
+                + (addDom ? "+" + bn : "")
+                + ((addDom || appendDom) ? "+ID" : "")
+                + "]");
+    }
 
 }
index c2e800789f9b4dff7cc6d104b8f78ac9fd40086d..e66753480e45e32201e8846fb74e76c32c6e2d22 100644 (file)
@@ -7,55 +7,98 @@ package org.xenoserver.control;
 
 import java.io.PrintWriter;
 
+/**
+ * A virtual block device; a mapping from a domain-specific number to a virtual
+ * disk with associated access mode.
+ */
 public class VirtualBlockDevice {
-  String key;
-  int domain;
-  int vbdnum;
-  Mode mode; /* rw or ro */
-
-  String dump(boolean title) {
-    StringBuffer sb = new StringBuffer();
-
-    if (title) {
-      sb.append("  key         dom vbd mode\n");
-    } else {
-      sb.append(
-        "  "
-          + key
-          + "  "
-          + Library.format(domain, 3, 0)
-          + " "
-          + Library.format(vbdnum, 3, 0)
-          + " "
-          + mode.toString()
-          + "\n");
+    /** The virtual disk which this block device maps onto. */
+    private VirtualDisk vd;
+    /** The domain in which this block device exists. */
+    private int domain;
+    /** The block device number in that domain. */
+    private int vbdNum;
+    /** The access mode within that domain. */
+    private Mode mode;
+
+    /**
+     * Constructor for VirtualBlockDevice.
+     * @param vd The virtual disk to map to.
+     * @param domain The domain to create the device in.
+     * @param vbdNum The number for the device.
+     * @param mode The access mode.
+     */
+    VirtualBlockDevice(
+        VirtualDisk vd,
+        int domain,
+        int vbdNum,
+        Mode mode) {
+        this.vd = vd;
+        this.domain = domain;
+        this.vbdNum = vbdNum;
+        this.mode = mode;
+    }
+
+    // TODO: get rid of this method
+    String dump(boolean title) {
+        StringBuffer sb = new StringBuffer();
+
+        if (title) {
+            sb.append("  key         dom vbd mode\n");
+        } else {
+            sb.append(
+                "  "
+                    + vd.getKey()
+                    + "  "
+                    + Library.format(domain, 3, false)
+                    + " "
+                    + Library.format(vbdNum, 3, false)
+                    + " "
+                    + mode.toString()
+                    + "\n");
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * Dump the virtual block device as XML.
+     * @param out The writer to dump to.
+     */
+    void dumpAsXML(PrintWriter out) {
+        out.println("  <virtual_block_device>");
+        out.println("    <key>" + vd.getKey() + "</key>");
+        out.println("    <domain>" + domain + "</domain>");
+        out.println("    <vbdnum>" + vbdNum + "</vbdnum>");
+        out.println("    <mode>" + mode + "</mode>");
+        out.println("  </virtual_block_device>");
     }
 
-    return sb.toString();
-  }
-
-  void dump_xml(PrintWriter out) {
-    out.println("  <virtual_block_device>");
-    out.println("    <key>" + key + "</key>");
-    out.println("    <domain>" + domain + "</domain>");
-    out.println("    <vbdnum>" + vbdnum + "</vbdnum>");
-    out.println("    <mode>" + mode + "</mode>");
-    out.println("  </virtual_block_device>");
-  }
-
-  public String getKey() {
-    return key;
-  }
-
-  public int getDomain() {
-    return domain;
-  }
-
-  public int getVBDNum() {
-    return vbdnum;
-  }
-
-  public Mode getMode() {
-    return mode;
-  }
+    /**
+     * @return This device's virtual disk.
+     */
+    public VirtualDisk getVirtualDisk() {
+        return vd;
+    }
+
+    /**
+     * @return The domain this device exists in.
+     */
+    public int getDomain() {
+        return domain;
+    }
+
+    /**
+     * @return The device number within its domain.
+     */
+    public int getVbdNum() {
+        return vbdNum;
+    }
+
+    /**
+     * @return This device's access mode.
+     */
+    public Mode getMode() {
+        return mode;
+    }
 }
index 460570f2d3a0e78c5b9376c5d828827dddf5f93f..70f61f47790de006c764c6dc38135f4432d2577c 100644 (file)
@@ -10,172 +10,224 @@ import java.util.Date;
 import java.util.Iterator;
 import java.util.Vector;
 
+/**
+ * A single virtual disk. This may be used by multiple virtual block devices.
+ */
 public class VirtualDisk {
-  String name;
-  String key;
-  Date expiry;
-  Vector extents;
-
-  VirtualDisk(String name, Date expiry, String key) {
-    this.name = name;
-    if ( key == null )
-      this.key = generate_key();
-    else
-      this.key = key;
-    this.expiry = expiry;
-    extents = new Vector();
-  }
-
-  VirtualDisk(String name) {
-    this(name, null, null);
-  }
-
-  VirtualDisk(String name, Date expiry) {
-    this(name, expiry, null);
-  }
-
-  /*
-   * generate a unique key for this virtual disk.
-   * for now, just generate a 10 digit number
-   */
-  String generate_key() {
-    return Long.toString(1000000000l + (long) (Math.random() * 8999999999l));
-  }
-
-  void set_expiry(Date expiry) {
-    this.expiry = expiry;
-  }
-
-  public void add_extent(Extent extent) {
-    extents.add(extent);
-  }
-
-  public Extent remove_extent() {
-    Extent e;
-
-    if (extents.size() > 0) {
-      e = (Extent) extents.remove(0);
-    } else {
-      e = null;
-    }
-
-    return e;
-  }
-
-  String dump_xen(VirtualBlockDevice vbd) {
-    StringBuffer sb = new StringBuffer();
-
-    sb.append(
-      "domain:"
-        + vbd.domain
-        + " "
-        + vbd.mode.toString()
-        + " "
-        + "segment:"
-        + vbd.vbdnum
-        + " "
-        + "extents:"
-        + extents.size()
-        + " ");
-    for (int loop = 0; loop < extents.size(); loop++) {
-      Extent e = (Extent) extents.get(loop);
-      sb.append(
-        "(disk:"
-          + e.disk
-          + " "
-          + "offset:"
-          + e.offset
-          + " "
-          + "size:"
-          + e.size
-          + ")");
-    }
-    return sb.toString();
-  }
-
-  void dump_xml(PrintWriter out) {
-    out.println("  <virtual_disk>");
-    out.println("    <name>" + name + "</name>");
-    out.println("    <key>" + key + "</key>");
-    if (expiry == null) {
-      out.println("    <expiry>0</expiry>");
-    } else {
-      out.println("    <expiry>" + expiry.getTime() + "</expiry>");
-    }
-    out.println("    <extents>");
-    for (int loop = 0; loop < extents.size(); loop++) {
-      Extent e = (Extent) extents.get(loop);
-      out.println("      <extent>");
-      out.println("        <disk>" + e.disk + "</disk>");
-      out.println("        <size>" + e.size + "</size>");
-      out.println("        <offset>" + e.offset + "</offset>");
-      out.println("      </extent>");
-    }
-    out.println("    </extents>");
-    out.println("  </virtual_disk>");
-
-    return;
-  }
-
-  /*
-   * Add a partition as a XenoPartition.
-   * Chop the partition in to extents and of size "size" sectors
-   * and add them to the virtual disk.
-   */
-
-  void add_new_partition(Partition partition, long size) {
-    int loop;
-
-    for (loop = 0; loop < partition.nr_sects / size; loop++) {
-      Extent extent = new Extent();
-
-      extent.disk = partition.major << 8;
-      extent.disk = extent.disk | (partition.minor >> 5) << 5;
-      extent.size = size;
-      extent.offset = partition.start_sect + (size * loop);
-
-      add_extent(extent);
-    }
-
-    return;
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public String getKey() {
-    return key;
-  }
-
-  public Date getExpiry() {
-    return expiry;
-  }
-
-  public int getExtentCount() {
-    return extents.size();
-  }
-
-  public Extent getExtent(int index) {
-    return (Extent) extents.get(index);
-  }
-
-  /**
-   * @return Total size of this virtual disk in sectors.
-   */
-  public long getSize() {
-    long size = 0;
-    Iterator i = extents.iterator();
-    while ( i.hasNext() ) {
-      size += ((Extent) i.next()).getSize();
-    }
-    return size;
-  }
-  
-  /**
-   * @return An iterator over all extents in the disk.
-   */
-  public Iterator iterator() {
-    return extents.iterator();
-  }
+    /** The name of this virtual disk. */
+    private String name;
+    /** The key of this virtual disk (unique). */
+    private String key;
+    /** The expiry time of this virtual disk, or null for never. */
+    private Date expiry;
+    /** The extent list for this virtual disk. */
+    private Vector extents;
+
+    /**
+     * Construct a new virtual disk, specifying all parameters.
+     * @param name Name of the new disk.
+     * @param expiry Expiry time, or null for never.
+     * @param key Key for the new disk, or null to autogenerate.
+     */
+    VirtualDisk(String name, Date expiry, String key) {
+        this.name = name;
+        if (key == null) {
+            this.key = generateKey();
+        } else {
+            this.key = key;
+        }
+        this.expiry = expiry;
+        extents = new Vector();
+    }
+
+    /**
+     * Construct a new virtual disk, with automatically generated key and no expiry.
+     * @param name Name of the new disk.
+     */
+    VirtualDisk(String name) {
+        this(name, null, null);
+    }
+
+    /**
+     * Construct a new virtual disk, with automatically generated key.
+     * @param name Name of the new disk.
+     * @param expiry Expiry time, or null for never.
+     */
+    VirtualDisk(String name, Date expiry) {
+        this(name, expiry, null);
+    }
+
+    /**
+     * Generate a unique key for this virtual disk.
+     * For now, just generate a 10 digit number.
+     * @return A unique key.
+     */
+    private static String generateKey() {
+        return Long.toString(
+            1000000000L + (long) (Math.random() * 8999999999L));
+    }
+
+    /**
+     * Add an extent to this disk.
+     * @param extent The extent to add.
+     */
+    void addExtent(Extent extent) {
+        extents.add(extent);
+    }
+
+    /**
+     * Remove the first extent from this disk.
+     * @return The extent removed, or null if there are no extents.
+     */
+    Extent removeExtent() {
+        Extent e;
+
+        if (extents.size() > 0) {
+            e = (Extent) extents.remove(0);
+        } else {
+            e = null;
+        }
+
+        return e;
+    }
+
+    /**
+     * Form a string suitable for passing into the XenoLinux proc interface mapping
+     * the given VBD to this virtual disk.
+     * @param vbd The virtual block device to map.
+     * @return A XenoLinux /proc string.
+     */
+    String dumpForXen(VirtualBlockDevice vbd) {
+        StringBuffer sb = new StringBuffer();
+
+        sb.append(
+            "domain:"
+                + vbd.getDomain()
+                + " "
+                + vbd.getMode().toString()
+                + " "
+                + "segment:"
+                + vbd.getVbdNum()
+                + " "
+                + "extents:"
+                + extents.size()
+                + " ");
+        for (int loop = 0; loop < extents.size(); loop++) {
+            Extent e = (Extent) extents.get(loop);
+            sb.append(
+                "(disk:"
+                    + e.getDisk()
+                    + " "
+                    + "offset:"
+                    + e.getOffset()
+                    + " "
+                    + "size:"
+                    + e.getSize()
+                    + ")");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Dump the virtual disk as XML.
+     * @param out The writer to dump to.
+     */
+    void dumpAsXML(PrintWriter out) {
+        out.println("  <virtual_disk>");
+        out.println("    <name>" + name + "</name>");
+        out.println("    <key>" + key + "</key>");
+        if (expiry == null) {
+            out.println("    <expiry>0</expiry>");
+        } else {
+            out.println("    <expiry>" + expiry.getTime() + "</expiry>");
+        }
+        out.println("    <extents>");
+        for (int loop = 0; loop < extents.size(); loop++) {
+            Extent e = (Extent) extents.get(loop);
+            out.println("      <extent>");
+            out.println("        <disk>" + e.getDisk() + "</disk>");
+            out.println("        <size>" + e.getSize() + "</size>");
+            out.println("        <offset>" + e.getOffset() + "</offset>");
+            out.println("      </extent>");
+        }
+        out.println("    </extents>");
+        out.println("  </virtual_disk>");
+
+        return;
+    }
+
+    /**
+     * Add a partition as a XenoPartition.
+     * Chop the partition in to extents and add them to this virtual disk.
+     * @param partition The partition to add.
+     * @param extentSize The number of sectors to use for each extent. 
+     */
+    void addPartition(Partition partition, long extentSize) {
+        int loop;
+
+        for (loop = 0; loop < partition.getNumSects() / extentSize; loop++) {
+            Extent extent =
+                new Extent(
+                    partition.getDisk(),
+                    extentSize,
+                    partition.getStartSect() + (extentSize * loop));
+
+            addExtent(extent);
+        }
+    }
+
+    /**
+     * @return The name of this virtual disk.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * @return The key of this virtual disk.
+     */
+    public String getKey() {
+        return key;
+    }
+
+    /**
+     * @return The expiry time of this virtual disk.
+     */
+    public Date getExpiry() {
+        return expiry;
+    }
+
+    /**
+     * @return The number of extents in this virtual disk.
+     */
+    public int getExtentCount() {
+        return extents.size();
+    }
+
+    /**
+     * @return Total size of this virtual disk in sectors.
+     */
+    public long getSize() {
+        long size = 0;
+        Iterator i = extents.iterator();
+        while (i.hasNext()) {
+            size += ((Extent) i.next()).getSize();
+        }
+        return size;
+    }
+
+    /**
+     * @return An iterator over all extents in the disk.
+     */
+    public Iterator extents() {
+        return extents.iterator();
+    }
+
+    /**
+     * Reset the expiry time for this virtual disk.
+     * @param expiry The new expiry time, or null for never.
+     */
+    public void refreshExpiry(Date expiry) {
+        this.expiry = expiry;
+    }
 }
index e2d1e6d6cc17c05b0a1d255823269bbd16d823c3..7ac5e79e4dfae1a367b5566e2776f09f18444307 100644 (file)
@@ -7,230 +7,216 @@ package org.xenoserver.control;
 
 import java.io.PrintWriter;
 import java.util.Date;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
 
 /**
  * VirtualDiskManager manages the list of virtual disks on the machine. It is
  * a Singleton which automatically initialises itself on first class reference.
  */
 public class VirtualDiskManager {
-  public static final VirtualDiskManager it = new VirtualDiskManager();
-  VirtualDisk free_disk;
-  Vector virtual_disks;
-  Hashtable virtual_block_devices;
-  Hashtable key_hash;
-
-  private VirtualDiskManager() {
-    free_disk = new VirtualDisk("free");
-
-    virtual_disks = new Vector(10, 5);
-    flush_virtual_block_devices();
-    key_hash = new Hashtable(100);
-  }
-
-  public VirtualDisk get_virtual_disk_key(String key) {
-    return ((VirtualDisk) key_hash.get(key));
-  }
-
-  public void add_xeno_partition(Partition partition, long size) {
-    free_disk.add_new_partition(partition, size);
-    return;
-  }
-
-  /*
-   * create a new virtual disk
-   */
-
-  public VirtualDisk create_virtual_disk(String name, long size, Date expiry) {
-    VirtualDisk vd = new VirtualDisk(name, expiry);
-
-    if ( free_disk.getSize() < size )
-      return null;
-    
-    while (size > 0) {
-      Extent e;
-
-      e = free_disk.remove_extent();
-      if (e == null) {
-        return null;
-      }
-      size -= e.size;
-      vd.add_extent(e);
-    }
-
-    add_virtual_disk(vd);
-
-    return vd;
-  }
-
-  /*
-   * delete a new virtual disk.  extents go back into the free pool
-   */
-
-  public void delete_virtual_disk(String key) {
-    VirtualDisk vd;
-
-    vd = (VirtualDisk) key_hash.get(key);
-    if (vd != null) {
-      Extent e;
-
-      key_hash.remove(key);
-      virtual_disks.remove(vd);
-
-      e = vd.remove_extent();
-      while (e != null) {
-        free_disk.add_extent(e);
-        e = vd.remove_extent();
-      }
-    }
-    return;
-  }
-
-  /*
-   * reset the expiry time for a virtual disk
-   */
-
-  public void refresh_virtual_disk(String key, Date expiry) {
-    VirtualDisk vd = (VirtualDisk) key_hash.get(key);
-    if (vd != null) {
-      vd.set_expiry(expiry);
-    }
-  }
-
-  /*
-   * create a new virtual block device
-   */
-  public VirtualBlockDevice create_virtual_block_device(
-    String key,
-    int domain,
-    int vbd_num,
-    String mode) {
-    VirtualBlockDevice vbd = new VirtualBlockDevice();
-    VirtualDisk vd = get_virtual_disk_key(key);
-
-    if (vd == null) {
-      System.err.println(
-        "create virtual block device error: unknown key " + "[" + key + "]");
-      return null;
-    }
-
-    vbd.key = key;
-    vbd.domain = domain;
-    vbd.vbdnum = vbd_num;
-
-    if (mode.equals(Mode.READ_ONLY.toString())
-      || mode.equals("RO")
-      || mode.equals("ro")) {
-      vbd.mode = Mode.READ_ONLY;
-    } else if (
-      mode.equals(Mode.READ_WRITE.toString())
-        || mode.equals("RW")
-        || mode.equals("rw")) {
-      vbd.mode = Mode.READ_WRITE;
-    } else {
-      System.err.println(
-        "create virtual block device error: unknown mode " + "[" + mode + "]");
-      return null;
-    }
-
-    add_virtual_block_device(vbd);
-
-    return vbd;
-  }
-
-  /*
-   * delete a virtual block device 
-   */
-  public void delete_virtual_block_device(int domain, int vbd_num) {
-    Object hash = get_vbd_hash(domain, vbd_num);
-    virtual_block_devices.remove(hash);
-  }
-
-  /*
-   * flush all virtual block devices
-   */
-  public void flush_virtual_block_devices() {
-    /* isn't automatic garbage collection wonderful? */
-    virtual_block_devices = new Hashtable(100);
-  }
-
-  public void add_virtual_disk(VirtualDisk vd) {
-    virtual_disks.add(vd);
-    key_hash.put(vd.getKey(), vd);
-  }
-
-  public void add_virtual_block_device(VirtualBlockDevice vbd) {
-    Object hash = get_vbd_hash(vbd.domain, vbd.vbdnum);
-    virtual_block_devices.put(hash, vbd);
-  }
-
-  Object get_vbd_hash(int domain, int vbd_num) {
-    return new Integer(domain * 16 + vbd_num);
-  }
-
-  public void add_free(VirtualDisk vd) {
-    free_disk = vd;
-  }
-
-  public String dump_virtualblockdevices() {
-    StringBuffer sb = new StringBuffer();
-    boolean first = true;
-
-    for (Enumeration enumeration = virtual_block_devices.elements();
-      enumeration.hasMoreElements();
-      ) {
-      VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
-      if (first) {
-        sb.append(vbd.dump(true));
-        first = false;
-      }
-
-      sb.append(vbd.dump(false));
-    }
-
-    return sb.toString();
-  }
-
-  public void dump_xml(PrintWriter out) {
-    out.println("<free>");
-    free_disk.dump_xml(out);
-    out.println("</free>");
-    out.println("<virtual_disks>");
-    for (int i = 0; i < virtual_disks.size(); i++) {
-      VirtualDisk vd = (VirtualDisk) virtual_disks.get(i);
-      vd.dump_xml(out);
-    }
-    out.println("</virtual_disks>");
-    out.println("<virtual_block_devices>");
-    for (Enumeration enumeration = virtual_block_devices.elements();
-      enumeration.hasMoreElements();
-      ) {
-      VirtualBlockDevice vbd = (VirtualBlockDevice) enumeration.nextElement();
-      vbd.dump_xml(out);
-    }
-
-    out.println("</virtual_block_devices>");
-
-    return;
-  }
-
-  /*************************************************************************/
-
-  public int getVirtualDiskCount() {
-    return virtual_disks.size();
-  }
-
-  public VirtualDisk getVirtualDisk(int index) {
-    return (VirtualDisk) virtual_disks.get(index);
-  }
-
-  public VirtualDisk getFreeVirtualDisk() {
-    return free_disk;
-  }
-
-  public Enumeration getVirtualBlockDevices() {
-    return virtual_block_devices.elements();
-  }
+    /** The single VDM reference. */
+    public static final VirtualDiskManager IT = new VirtualDiskManager();
+    /** The free-space disk. */
+    private VirtualDisk freeDisk;
+    /** The map of keys to virtual disks. */
+    private LinkedHashMap virtualDisks = new LinkedHashMap(100);
+    /** The map of (domain,vbdnum) to virtual block devices. */
+    private LinkedHashMap virtualBlockDevices = new LinkedHashMap(100);
+
+    /**
+     * VDM constructor, private as it's a singleton.
+     */
+    private VirtualDiskManager() {
+        freeDisk = new VirtualDisk("free");
+    }
+
+    /**
+     * Get the virtual disk with the specified key.
+     * @param key The key to look for.
+     * @return The virtual disk, or null if not found.
+     */
+    public VirtualDisk getVirtualDisk(String key) {
+        return ((VirtualDisk) virtualDisks.get(key));
+    }
+
+    /**
+     * Add a new partition to the free space list in the disk manager.
+     * @param partition The partition to add.
+     * @param chunkSize The chunk size to split the partition into, in sectors. 
+     */
+    public void addPartition(Partition partition, long chunkSize) {
+        freeDisk.addPartition(partition, chunkSize);
+    }
+
+    /**
+     * Create a new virtual disk.
+     * @param name The disk name to use.
+     * @param size The number of sectors to allocate.
+     * @param expiry The expiry time, or null for never.
+     * @return null if not enough space is available
+     */
+    public VirtualDisk createVirtualDisk(String name, long size, Date expiry) {
+        if (freeDisk.getSize() < size) {
+            return null;
+        }
+
+        VirtualDisk vd = new VirtualDisk(name, expiry);
+
+        while (size > 0) {
+            Extent e;
+
+            e = freeDisk.removeExtent();
+            if (e == null) {
+                return null;
+            }
+            size -= e.getSize();
+            vd.addExtent(e);
+        }
+
+        insertVirtualDisk(vd);
+
+        return vd;
+    }
+
+    /**
+     * Delete a virtual disk, and put its extents back into the free pool.
+     * @param key The key of the disk to delete.
+     */
+    public void deleteVirtualDisk(String key) {
+        VirtualDisk vd;
+
+        vd = (VirtualDisk) virtualDisks.get(key);
+        if (vd != null) {
+            Extent e;
+
+            virtualDisks.remove(key);
+
+            e = vd.removeExtent();
+            while (e != null) {
+                freeDisk.addExtent(e);
+                e = vd.removeExtent();
+            }
+        }
+    }
+
+    /**
+     * Create a new virtual block device.
+     * @param vd The virtual disk to expose.
+     * @param domain The domain to create the device for.
+     * @param vbdNum The block device number to use.
+     * @param mode The mode to create the device with.
+     * @return The newly created virtual block device.
+     */
+    public VirtualBlockDevice createVirtualBlockDevice(
+        VirtualDisk vd,
+        int domain,
+        int vbdNum,
+        Mode mode) {
+        VirtualBlockDevice vbd =
+            new VirtualBlockDevice(vd, domain, vbdNum, mode);
+
+        insertVirtualBlockDevice(vbd);
+
+        return vbd;
+    }
+
+    /**
+     * Delete a virtual block device.
+     * @param domain Domain owning the device.
+     * @param vbdNum The vbd number within the domain.
+     */
+    public void deleteVirtualBlockDevice(int domain, int vbdNum) {
+        Object hash = hashVBD(domain, vbdNum);
+        virtualBlockDevices.remove(hash);
+    }
+
+    /**
+     * Flush all virtual block devices.
+     */
+    public void flushVirtualBlockDevices() {
+        /* isn't automatic garbage collection wonderful? */
+        virtualBlockDevices = new LinkedHashMap(100);
+    }
+
+    /**
+     * Insert a new virtual disk into the map.
+     * @param vd The disk to insert.
+     */
+    void insertVirtualDisk(VirtualDisk vd) {
+        virtualDisks.put(vd.getKey(), vd);
+    }
+
+    /**
+     * Insert a new virtual block device into the map.
+     * @param vbd The device to insert.
+     */
+    void insertVirtualBlockDevice(VirtualBlockDevice vbd) {
+        Object hash = hashVBD(vbd.getDomain(), vbd.getVbdNum());
+        virtualBlockDevices.put(hash, vbd);
+    }
+
+    /**
+     * Hash a virtual block device.
+     * @param domain The VBD's domain.
+     * @param vbdNum The VBD's number within the domain.
+     * @return A suitable hash key.
+     */
+    Object hashVBD(int domain, int vbdNum) {
+        return new Integer(domain * 16 + vbdNum);
+    }
+
+    /**
+     * Set a new free disk.
+     * @param vd The free disk to set.
+     */
+    void setFreeDisk(VirtualDisk vd) {
+        freeDisk = vd;
+    }
+
+    /**
+     * Dump the data in the VirtualDiskManager in XML form.
+     * @param out The output writer to dump to.
+     */
+    void dumpAsXML(PrintWriter out) {
+        out.println("<free>");
+        freeDisk.dumpAsXML(out);
+        out.println("</free>");
+        out.println("<virtual_disks>");
+        Iterator i = virtualDisks.values().iterator();
+        while (i.hasNext()) {
+            VirtualDisk vd = (VirtualDisk) i.next();
+            vd.dumpAsXML(out);
+        }
+        out.println("</virtual_disks>");
+        out.println("<virtual_block_devices>");
+        i = virtualBlockDevices.values().iterator();
+        while (i.hasNext()) {
+            VirtualBlockDevice vbd = (VirtualBlockDevice) i.next();
+            vbd.dumpAsXML(out);
+        }
+
+        out.println("</virtual_block_devices>");
+    }
+
+    /**
+     * @return The free disk.
+     */
+    public VirtualDisk getFreeDisk() {
+        return freeDisk;
+    }
+
+    /**
+     * @return An iterator over the virtual block devices.
+     */
+    public Iterator getVirtualBlockDevices() {
+        return virtualBlockDevices.values().iterator();
+    }
+
+    /**
+     * @return An iterator over the virtual disks.
+     */
+    public Iterator getVirtualDisks() {
+        return virtualDisks.values().iterator();
+    }
 }
index 55bc3a9c122002bbef0eb798dbfd996b5bd65993..3988d8407c553f712d8b9160cc1f36fae2648492 100644 (file)
@@ -19,107 +19,102 @@ import javax.xml.parsers.ParserConfigurationException;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
-public class
-XML
-{
-  static Document document = null;
 
-  /*
-   * dump partition manager and virtual disk manager state to filename
-   */
-
-  public static void
-  dump_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
-  {
-    PrintWriter out;
+/**
+ * Utility class for loading and saving state through XML files.
+ */
+public class XML {
+    /** The document we are reading/writing. */
+    private static Document document = null;
 
-    try
-    {
-      out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
-    }
-    catch (IOException e)
-    {
-      System.err.println ("XML.dump_state error [" + filename + "]");
-      System.err.println (e);
-      return;
-    }
+    /**
+     * Save the state of the managers to the configuration file given.
+     * @param pm The PartitionManager to save.
+     * @param vdm The VirtualDiskManager to save.
+     * @param filename The configuration filename to save to.
+     */
+    public static void saveState(
+        PartitionManager pm,
+        VirtualDiskManager vdm,
+        String filename) {
+        PrintWriter out;
 
-    out.println("<?xml version=\"1.0\"?>");
-    out.println("<vdmanager>");
-    pm.dump_xml(out);
-    vdm.dump_xml(out);
-    out.println("</vdmanager>");
+        try {
+            out = new PrintWriter(new BufferedWriter(new FileWriter(filename)));
+        } catch (IOException e) {
+            System.err.println("XML.dump_state error [" + filename + "]");
+            System.err.println(e);
+            return;
+        }
 
-    out.close();
-    return;
-  }
+        out.println("<?xml version=\"1.0\"?>");
+        out.println("<vdmanager>");
+        pm.dumpAsXML(out);
+        vdm.dumpAsXML(out);
+        out.println("</vdmanager>");
 
-  /*
-   * load partition manager and virtual disk manager state from filename
-   */
-  public static void
-  load_state (PartitionManager pm, VirtualDiskManager vdm, String filename)
-  {
-    if (document == null)
-    {
-      load_file (filename);
+        out.close();
+        return;
     }
 
-    XMLHelper.parse(pm, vdm, document);
-  }
+    /**
+     * Load the state of the managers from the given configuration file.
+     * @param pm The PartitionManager to load.
+     * @param vdm The VirtualDomainManager to load.
+     * @param filename The filename to read the configuration from.
+     */
+    public static void loadState(
+        PartitionManager pm,
+        VirtualDiskManager vdm,
+        String filename) {
+        if (document == null) {
+            loadFile(filename);
+        }
 
-  /*
-   * load XML from disk
-   */
-  static void
-  load_file (String filename)
-  {
-    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-    // factory.setNamespaceAware(true);
-    // factory.setValidating(true);
+        XMLHelper.parse(pm, vdm, document);
+    }
 
-    try
-    {
-      File file = new File(filename);
+    /**
+     * Load an XML file and parse it into a Document.
+     * @param filename The file to load.
+     */
+    private static void loadFile(String filename) {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 
-      DocumentBuilder builder = factory.newDocumentBuilder();
-      document = builder.parse(file);
-    }
-    catch (SAXParseException spe)               /* error generated by parser */
-    {
-      System.err.println ("xml parser exception on line " + 
-                         spe.getLineNumber() + 
-                         " for uri " + spe.getSystemId());
-      System.err.println (spe.getMessage());
+        try {
+            File file = new File(filename);
 
-      Exception x = spe;
-      if (spe.getException() != null)
-       x = spe.getException();
-      x.printStackTrace();
-      System.exit(1);
-    }
-    catch (SAXException sxe)
-    {
-      Exception e = sxe;
-      if (sxe.getException() != null)
-       e = sxe.getException();
-      e.printStackTrace();
-      System.exit(1);
-    }
-    catch (ParserConfigurationException pce)
-    {
-      pce.printStackTrace();
-    }
-    catch (FileNotFoundException fnfe)
-    {
-      System.err.println ("warning: state file not found [" +
-                         filename + "]");
-    }
-    catch (IOException ioe)
-    {
-      ioe.printStackTrace();
+            DocumentBuilder builder = factory.newDocumentBuilder();
+            document = builder.parse(file);
+        } catch (SAXParseException spe) /* error generated by parser */ {
+            System.err.println(
+                "xml parser exception on line "
+                    + spe.getLineNumber()
+                    + " for uri "
+                    + spe.getSystemId());
+            System.err.println(spe.getMessage());
+
+            Exception x = spe;
+            if (spe.getException() != null) {
+                x = spe.getException();
+            }
+            x.printStackTrace();
+            System.exit(1);
+        } catch (SAXException sxe) {
+            Exception e = sxe;
+            if (sxe.getException() != null) {
+                e = sxe.getException();
+            }
+            e.printStackTrace();
+            System.exit(1);
+        } catch (ParserConfigurationException pce) {
+            pce.printStackTrace();
+        } catch (FileNotFoundException fnfe) {
+            System.err.println(
+                "warning: state file not found [" + filename + "]");
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        }
+        return;
     }
-    return;
-  }
 }
index ad1c3f50e18823fae685a8f043cc4fbbed79517a..d495eb9c2cd3a7de7443b3c23ce0c87dfaebbe52 100644 (file)
@@ -8,201 +8,216 @@ package org.xenoserver.control;
 import java.util.Date;
 
 import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
-public class
-XMLHelper
-{
-  static void
-  dump_document (Document document)
-  {
-    dump_element(document.getDocumentElement(), 0);
-  }
-
-  static void
-  dump_element (Element element, int indent)
-  {
-    NodeList nl = element.getChildNodes();
-
-    System.out.println ("<" + element.getTagName() + ">");
-    dump_nodelist(nl, indent + 1);
-    System.out.println("</" + element.getTagName() + ">");
-  }
-
-  static void
-  dump_nodelist (NodeList nl, int indent)
-  {
-    for (int loop = 0; loop < nl.getLength(); loop++)
-    {
-      Node node = nl.item(loop);
-      switch (node.getNodeType())
-      {
-       case Node.ELEMENT_NODE : 
-       {
-         dump_element((Element)node, indent);
-         break;
-       }
-       case Node.TEXT_NODE :
-       {
-         System.out.println("TEXT: " + node.getNodeValue());
-         break;
-       }
-       default :
-       {
-         System.out.println("NODE: " + node.getNodeType());
-       }
-      }
-    }
-  }
-
-  static Node 
-  get_subnode (String name, Node node) 
-  {
-    if (node.getNodeType() != Node.ELEMENT_NODE) 
-    {
-      System.err.println("Error: Search node not of element type");
-      return null;
+/**
+ * XMLHelper contains helper methods used to parse the XML state files.
+ */
+class XMLHelper {
+    /**
+     * Find a subnode with the specified name.
+     * @param name Name to look for.
+     * @param node Node from which to start search.
+     * @return The first subnode found, or null if none.
+     */
+    private static Node getSubNode(String name, Node node) {
+        if (node.getNodeType() != Node.ELEMENT_NODE) {
+            System.err.println("Error: Search node not of element type");
+            return null;
+        }
+
+        if (!node.hasChildNodes()) {
+            return null;
+        }
+
+        NodeList list = node.getChildNodes();
+        for (int i = 0; i < list.getLength(); i++) {
+            Node subnode = list.item(i);
+            if (subnode.getNodeType() == Node.ELEMENT_NODE) {
+                if (subnode.getNodeName() == name) {
+                    return subnode;
+                }
+            }
+        }
+        return null;
     }
 
-    if (!node.hasChildNodes()) return null;
-
-    NodeList list = node.getChildNodes();
-    for (int i=0; i < list.getLength(); i++) 
-    {
-      Node subnode = list.item(i);
-      if (subnode.getNodeType() == Node.ELEMENT_NODE) 
-      {
-       if (subnode.getNodeName() == name) return subnode;
-      }
-    }
-    return null;
-  }
-
-  static String 
-  get_text (Node node) 
-  {
-    StringBuffer result = new StringBuffer();
-    if (node==null || !node.hasChildNodes()) return "";
-
-    NodeList list = node.getChildNodes();
-    for (int i=0; i < list.getLength(); i++) 
-    {
-      Node subnode = list.item(i);
-      if (subnode.getNodeType() == Node.TEXT_NODE) 
-      {
-       result.append(subnode.getNodeValue());
-      }
-    }
-    return result.toString();
-  }
-
-  static void
-  parse (PartitionManager pm, VirtualDiskManager vdm, Document document)
-  {
-    if (document == null) return;
-
-    /* parse partitions */
-    parse_partitions(pm, document.getElementsByTagName("partition"));
-
-    /* parse virtual disks */
-    NodeList list = document.getElementsByTagName("virtual_disk");
-    for (int i = 0; i < list.getLength(); i++)
-    {
-      Node subnode = list.item(i);
-      String parent = subnode.getParentNode().getNodeName();
-      VirtualDisk vd =  parse_virtual_disk(subnode);
-
-      if (parent.equals("free"))
-      {
-       vdm.add_free(vd);
-      }
-      else if (parent.equals("virtual_disks"))
-      {
-       vdm.add_virtual_disk(vd);
-      }
-      else
-      {
-       System.out.println ("XML parse error: unknown parent for virtual_disk "
-                           + "[" + parent + "]");
-      }
+    /**
+     * Get all the text of a given node.
+     * @param node The node to examine.
+     * @return The node's text.
+     */
+    private static String getText(Node node) {
+        StringBuffer result = new StringBuffer();
+        if (node == null || !node.hasChildNodes()) {
+            return "";
+        }
+
+        NodeList list = node.getChildNodes();
+        for (int i = 0; i < list.getLength(); i++) {
+            Node subnode = list.item(i);
+            if (subnode.getNodeType() == Node.TEXT_NODE) {
+                result.append(subnode.getNodeValue());
+            }
+        }
+        return result.toString();
     }
 
-    /* parse virtual block devices */
-    parse_virtual_block_devices(vdm, document.getElementsByTagName("virtual_block_device"));
-
-    return;
-  }
-
-  static VirtualDisk
-  parse_virtual_disk(Node node)
-  {
-    VirtualDisk vd;
-    Date date = new Date();
-    NodeList list;
-
-    long timestamp = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("expiry", node)));
-    if ( timestamp == 0 )
-      date = null;
-    else
-      date.setTime( timestamp );
-    vd = new VirtualDisk(XMLHelper.get_text(XMLHelper.get_subnode("name", node)),
-                        date,
-                        XMLHelper.get_text(XMLHelper.get_subnode("key", node)));
-
-    list = XMLHelper.get_subnode("extents", node).getChildNodes();
-    for (int i = 0; i < list.getLength(); i++)
-    {
-      Node enode = list.item(i);
-
-      if (enode.getNodeType() == Node.ELEMENT_NODE &&
-         enode.getNodeName().equals("extent"))
-      {
-       Extent extent = new Extent();
-
-       extent.disk = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("disk", enode)));
-       extent.size = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("size", enode)));
-       extent.offset = Long.parseLong(XMLHelper.get_text(XMLHelper.get_subnode("offset", enode)));
-       vd.add_extent(extent);
-      }
+    /**
+     * Parse the given configuration document and configure the managers.
+     * @param pm PartitionManager instance to configure.
+     * @param vdm VirtualDomainManager instance to configure.
+     * @param document Document to parse.
+     */
+    static void parse(
+        PartitionManager pm,
+        VirtualDiskManager vdm,
+        Document document) {
+        if (document == null) {
+            return;
+        }
+
+        /* parse partitions */
+        parsePartitions(pm, document.getElementsByTagName("partition"));
+
+        /* parse virtual disks */
+        NodeList list = document.getElementsByTagName("virtual_disk");
+        for (int i = 0; i < list.getLength(); i++) {
+            Node subnode = list.item(i);
+            String parent = subnode.getParentNode().getNodeName();
+            VirtualDisk vd = parseVirtualDisk(subnode);
+
+            if (parent.equals("free")) {
+                vdm.setFreeDisk(vd);
+            } else if (parent.equals("virtual_disks")) {
+                vdm.insertVirtualDisk(vd);
+            } else {
+                System.out.println(
+                    "XML parse error: unknown parent for virtual_disk "
+                        + "["
+                        + parent
+                        + "]");
+            }
+        }
+
+        /* parse virtual block devices */
+        parseVirtualBlockDevices(
+            vdm,
+            document.getElementsByTagName("virtual_block_device"));
+
+        return;
     }
 
-    return vd;
-  }
-
-  static void
-  parse_partitions (PartitionManager pm, NodeList nl)
-  {
-    Partition partition;
-
-    for (int loop = 0; loop < nl.getLength(); loop++)
-    {
-      Node node = nl.item(loop);
-
-      partition = new Partition();
-      partition.major = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("major", node)));
-      partition.minor = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("minor", node)));
-      partition.blocks = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("blocks", node)));
-      partition.start_sect = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("start_sect", node)));
-      partition.nr_sects = Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("nr_sects", node)));
-      partition.name = XMLHelper.get_text(XMLHelper.get_subnode("name", node));
+    /**
+     * Parse a node representing a virtual disk.
+     * @param node The node to parse.
+     * @return The VirtualDisk this node represents.
+     */
+    private static VirtualDisk parseVirtualDisk(Node node) {
+        VirtualDisk vd;
+        Date date = new Date();
+        NodeList list;
+
+        long timestamp =
+            Long.parseLong(
+                XMLHelper.getText(XMLHelper.getSubNode("expiry", node)));
+        if (timestamp == 0) {
+            date = null;
+        } else {
+            date.setTime(timestamp);
+        }
+        vd =
+            new VirtualDisk(
+                XMLHelper.getText(XMLHelper.getSubNode("name", node)),
+                date,
+                XMLHelper.getText(XMLHelper.getSubNode("key", node)));
+
+        list = XMLHelper.getSubNode("extents", node).getChildNodes();
+        for (int i = 0; i < list.getLength(); i++) {
+            Node enode = list.item(i);
+
+            if (enode.getNodeType() == Node.ELEMENT_NODE
+                && enode.getNodeName().equals("extent")) {
+                Extent extent =
+                    new Extent(
+                        Integer.parseInt(
+                            XMLHelper.getText(
+                                XMLHelper.getSubNode("disk", enode))),
+                        Long.parseLong(
+                            XMLHelper.getText(
+                                XMLHelper.getSubNode("size", enode))),
+                        Long.parseLong(
+                            XMLHelper.getText(
+                                XMLHelper.getSubNode("offset", enode))));
+                vd.addExtent(extent);
+            }
+        }
+
+        return vd;
+    }
 
-      pm.add_xeno_partition(partition);
+    /**
+     * Parse a list of partition nodes.
+     * @param pm The partition manager to configure.
+     * @param nl The list of partition nodes.
+     */
+    private static void parsePartitions(PartitionManager pm, NodeList nl) {
+        Partition partition;
+
+        for (int loop = 0; loop < nl.getLength(); loop++) {
+            Node node = nl.item(loop);
+
+            partition =
+                new Partition(
+                    Integer.parseInt(
+                        XMLHelper.getText(XMLHelper.getSubNode("major", node))),
+                    Integer.parseInt(
+                        XMLHelper.getText(XMLHelper.getSubNode("minor", node))),
+                    Integer.parseInt(
+                        XMLHelper.getText(
+                            XMLHelper.getSubNode("blocks", node))),
+                    Integer.parseInt(
+                        XMLHelper.getText(
+                            XMLHelper.getSubNode("start_sect", node))),
+                    Integer.parseInt(
+                        XMLHelper.getText(
+                            XMLHelper.getSubNode("nr_sects", node))),
+                    XMLHelper.getText(XMLHelper.getSubNode("name", node)),
+                    true);
+
+            pm.addXenoPartition(partition);
+        }
     }
-  }
-
-  static void
-  parse_virtual_block_devices (VirtualDiskManager vdm, NodeList nl)
-  {
-    for (int loop = 0; loop < nl.getLength(); loop++)
-    {
-      Node node = nl.item(loop);
-
-      vdm.create_virtual_block_device(XMLHelper.get_text(XMLHelper.get_subnode("key", node)),
-                                     Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("domain", node))),
-                                     Integer.parseInt(XMLHelper.get_text(XMLHelper.get_subnode("vbdnum", node))),
-                                     XMLHelper.get_text(XMLHelper.get_subnode("mode", node)));
+
+    /**
+     * Parse a list of virtual block device nodes.
+     * @param vdm The VirtualDiskManager to configure. 
+     * @param nl The node list.
+     */
+    private static void parseVirtualBlockDevices(
+        VirtualDiskManager vdm,
+        NodeList nl) {
+        for (int loop = 0; loop < nl.getLength(); loop++) {
+            Node node = nl.item(loop);
+            Mode mode;
+
+            if (XMLHelper
+                .getText(XMLHelper.getSubNode("mode", node))
+                .equals("rw")) {
+                mode = Mode.READ_WRITE;
+            } else {
+                mode = Mode.READ_ONLY;
+            }
+
+            vdm.createVirtualBlockDevice(
+                vdm.getVirtualDisk(
+                    XMLHelper.getText(XMLHelper.getSubNode("key", node))),
+                Integer.parseInt(
+                    XMLHelper.getText(XMLHelper.getSubNode("domain", node))),
+                Integer.parseInt(
+                    XMLHelper.getText(XMLHelper.getSubNode("vbdnum", node))),
+                mode);
+        }
     }
-  }
 }